Set-up

rm(list = ls())
library(dplyr)
library(wesanderson)
library(GillespieSSA)
library(tidyverse)

Background

The traditionally held belief that most modern infectious diseases emerged when humans began living in larger agricultural settlements has been challenged by studies of modern hunter-gatherers. This study will investigate which emerging pathogens may persist in hunter-gatherer groups by constructing a compartment model of infectious disease transmission that accounts for demography and multi-band structure. This study will look to understand how the critical community size required to sustain an outbreak is affected by host population dynamics. We show that metapopulation structure increases the probability of a respiratory pathogen with waning immunity persisting after 3 years. The probability of persistence increases with the number of sub-populations but is largely determined by the duration of immunity. Understanding the origins of infectious diseases is an important area of research that will lead to improved strategies for reducing their global burden.

This report will cover the full analysis undertaken to generate the results used in my MSc project. A full description of the research project aims and methods can be found in the final paper in the Hunter_Gatherer_models GitHub repository. Some code used in this project was adapted from the tutorials attached to the GillespieSSA package.

Model Parameter estimation

Agta Hunter-Gatherer Demography

Modern-day hunter-gatherers are often used to make inferences about pre-agricultural human populations. This study modeled the host population on a group of indigenous hunter-gatherers from the Northern Phillipines known as the Agta. Information regarding births, deaths and population size were obtain from a study conducted by Headland et al., (2011). Authors conducted a census-like survey of the Agta that followed $$4,300 individuals over the period of 1950-2010. This date was first explored to understand Agta demography.

agta_demo <- read.csv("Agta_Data/AgtaPopDynamics_Headland2007.csv")

ggplot(agta_demo, aes(x=Year)) +
  geom_line(aes(y=PopSize), colour = wes_palettes$Darjeeling1[1]) +
  geom_line(aes(y=Births), colour = wes_palettes$Darjeeling1[2]) +
  geom_line(aes(y=Deaths), colour = wes_palettes$Darjeeling1[3]) +
  theme_bw()

Population Size

hist(agta_demo$PopSize)

summary(agta_demo$PopSize)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  133.0   177.0   213.0   211.4   228.0   295.0 

Births

hist(agta_demo$Births)

summary(agta_demo$Births)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
   4.00    8.00   10.00   10.33   12.25   15.00       1 

Deaths

hist(agta_demo$Deaths)

summary(agta_demo$Deaths)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
  2.000   5.000   7.000   7.683  10.000  23.000       1 

Birth/Death rate per person per day

Birth rate was estimated from this data by taking the mean of the annual number of births divided by two times the annual number of females. This was then scaled appropriately to obtain the daily mean birth rate per person.

agta_demo <- agta_demo %>%
  mutate(Birth_rate = Births/(Female*2),
         Birth_rate_daily = (1 + Birth_rate) ^ (1/365) - 1,
         Death_rate = (Deaths/PopSize),
         Death_rate_daily = (1 + Death_rate) ^ (1/365) - 1,
         PopChange = (diff = PopSize - lag(PopSize, default = first(PopSize))),
         PopChange_rate = abs(PopChange)/PopSize,
         PopChange_rate_daily = (1 + PopChange_rate) ^ (1/365) - 1)
head(agta_demo)


hist(agta_demo$Birth_rate)

hist(agta_demo$Death_rate)


ggplot(agta_demo, aes(x=Year)) +
  geom_line(aes(y=Birth_rate), colour = wes_palettes$Darjeeling1[2]) +
  geom_line(aes(y=Death_rate), colour = wes_palettes$Darjeeling1[3]) +
  theme_bw()


demo_sum <- agta_demo %>%
  select(PopSize, Birth_rate, Birth_rate_daily, Death_rate, Death_rate_daily, PopChange_rate, PopChange_rate_daily) %>%
    summarise(across(
    .cols = is.numeric, 
    .fns = list(Mean = mean, SD = sd), na.rm = TRUE, 
    .names = "{col}_{fn}"
    ))
demo_sum 

demo_sum <- as.list(demo_sum)

Agta Band Size

Data regarding camp size of Agta hunter-gatherers was obtained from a study of 615 individuals from 15 camps in in the municipality of Palanan, the Northern Philippines published by Dyble et al. (2021).

# Import Camp data from Mark Dyble
camps.data <- read_csv("Agta_Data/camps.csv")
New names:Rows: 15 Columns: 9── Column specification ──────────────────────────────────────────────────────
Delimiter: ","
chr (1): camp_name
dbl (8): ...1, camp_total, camp_adult_men, camp_adult_women, camp_all_r, c...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(camps.data)
# Explore camp size
hist(camps.data$camp_total)


camp.size <- camps.data %>%
  summarise(mean = mean(camp_total),
            sd = sd(camp_total),
            min = min(camp_total),
            max = max(camp_total),
            var = var(camp_total))
camp.size

Pathogen X

For the purpose of this investigation we formulated a hypothetical respiratory pathogen, referred to as pathogen X. Taking into account the biological trade-offs between high transmissibility and high pathogenicity, pathogen X was decided to be highly infectious with a relatively low case fatality rate of 0.005. Transmission occurred via close contact with an infected individual. Infection was characterised by a latent period of 5.7 days followed by an infectious period of 5 days. Individuals who recovered from infection were immune for 100 days, after which immunity waned and individuals became susceptible to re-infection. Based on these characteristics, the parameters in table 1 were assumed and input into the final models.

Parameter Rate Value
\(\beta\) Transmission 0.6
\(\sigma\) Infectious 0.175
\(\gamma\) Recovery 0.2
\(\alpha\) Death from Infection 0.001
\(\omega\) Waning Immunity 0.01

Single Population Model

To investigate the persistence of a hypothetical respiratory pathogen in hunter-gatherers, this study chose to simulate disease transmission using a compartment model approach as outlined in the introduction. Two models were constructed to investigate compare the effect of metapopulation structure on disease persistence. This first describes the transmission of a pathogen within a single population with demography and waning immunity to re-infection over time.


Figure 1 - Flow diagram of SEIRS model of transmission
Figure 1 - Flow diagram of SEIRS model of transmission




\[\begin{align*} \frac{{{\mathrm{d}}S}}{{{\mathrm{d}}t}} & = \underbrace {\mu N}_{{\mathrm{birth}}}~ - ~\underbrace {\frac{\beta SI}{N}}_{{\mathrm{infection}}}~~ + \underbrace {\omega R}_{{\mathrm{lost}}\,{\mathrm{immunity}}} - \underbrace {\mu S}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}E}}{{{\mathrm{d}}t}} & = \underbrace {\frac{\beta SI}{N}}_{{\mathrm{infection}}}~ - ~\underbrace {\sigma E}_{{\mathrm{latency}}} - \underbrace {\mu E}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}I}}{{{\mathrm{d}}t}} & = \underbrace {\sigma E}_{{\mathrm{latency}}} - \underbrace {\gamma I}_{{\mathrm{recovery}}} - ~\underbrace {\left( {\mu + \alpha } \right)I}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}R}}{{{\mathrm{d}}t}} & = \underbrace {\gamma I}_{{\mathrm{recovery}}} - \underbrace {\omega R}_{{\mathrm{lost}}\ {\mathrm{immunity}}} - \underbrace {\mu R}_{{\mathrm{death}}} \end{align*}\]



Where transmission is frequency dependent, \({\frac{\beta SI}{N}}\), \(\frac{1}{\sigma}\) is the duration of the latent phase, \(\frac{1}{\gamma}\) is the duration of infection, \(\frac{1}{\omega}\) is the duration of immunity and death from infection occurs at the rate \(\alpha\). Individuals can be born into S and die naturally from any compartment at a rate of \(\mu\).

Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
N <-    sample(camps.data$camp_total, 1)    # Population size
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

names(x0) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Define functions to calculate R0 and expected number of susceptibles at equilibrium, and critical community size (Diekmann et al., 2012).

 R0 <- function(parms) {
   (parms$sigma/(parms$sigma + parms$mu)) * (parms$beta/parms$gamma + parms$mu + parms$alpha)
 } 
  
EIE <- function(R0, parms) {
  y = ((R0 - 1) * parms$omega) / (parms$gamma * R0)
  return(y)
}

CCS <- function(infectious_period, R0) {
  x = infectious_period/(23*365)           # Avg life life expexctancy of 23 (Gurven et al. 2007)
  y = 1/((x^2)*((1-(1/R0))^2))
  return(y)
}

Calculate Epidemic Statistics


# Calculate R0, expected number of infecteds at equilibrium, magnitude of oscillation and CCS
R0_single <- R0(parms)
R0_single
[1] 2.998695
EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single
[1] 0.03332608
expexted_infecteds <- EIE_single*N # number of expected infecteds at equilibrium
expexted_infecteds
[1] 0.7331737
sqrt(N) # magnitude of oscillations 
[1] 4.690416
CCS_single <- CCS(5, R0_single) # Average life expectancy as per Kaplan (crude)
CCS_single
[1] 6345604

Plot CCS by infectious period and R0

Run Single Population Model

# Run simulations with the Direct method
set.seed(21)
out <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data <- out$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot <- ggplot(data = plot_data, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot


ggsave(filename = "single_plot.pdf", 
       plot = single_plot,
       device = "pdf",
       width = 7, 
       height = 3,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
Error in grDevices::pdf(file = filename, ..., version = version) : 
  cannot open file '/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models/single_plot.pdf'
plot_data %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 25 with 14 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list <- list()
sim_list <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data <- out_100$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list[[i]] <- sim_data
}

sim_output <- bind_rows(sim_list)
# Summary table of endpoint data
sim_output <- sim_output %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output)

# Make Summary Table of output
sim_summary <- sim_output %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_0 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_0 <- out_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_0 <- ggplot(data = plot_data_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0 <- list()
sim_list_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_0 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0 <- out_100_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0[[i]] <- sim_data_0
}

sim_output_0 <- bind_rows(sim_list_0)
# Summary table of endpoint data
sim_output_0 <- sim_output_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0

# Make Summary Table of output
sim_summary_0 <- sim_output_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_1 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_1 <- out_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_1 <- ggplot(data = plot_data_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1 <- list()
sim_list_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_1 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1 <- out_100_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1[[i]] <- sim_data_1
}

sim_output_1 <- bind_rows(sim_list_1)
# Summary table of endpoint data
sim_output_1 <- sim_output_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1

# Make Summary Table of output
sim_summary_1 <- sim_output_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_3 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3 <- out_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3 <- ggplot(data = plot_data_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3 <- list()
sim_list_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_3 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3 <- out_100_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3[[i]] <- sim_data_3
}

sim_output_3 <- bind_rows(sim_list_3)
# Summary table of endpoint data
sim_output_3 <- sim_output_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3

# Make Summary Table of output
sim_summary_3 <- sim_output_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_7 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_7 <- out_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_7 <- ggplot(data = plot_data_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7 <- list()
sim_list_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_7 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7 <- out_100_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7[[i]] <- sim_data_7
}

sim_output_7 <- bind_rows(sim_list_7)
# Summary table of endpoint data
sim_output_7 <- sim_output_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7

# Make Summary Table of output
sim_summary_7 <- sim_output_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


# Run simulations with the Direct method
set.seed(4)
out_10 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_10 <- out_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_10 <- ggplot(data = plot_data_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10 <- list()
sim_list_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_10 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10 <- out_100_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10[[i]] <- sim_data_10
}

sim_output_10 <- bind_rows(sim_list_10)
# Summary table of endpoint data
sim_output_10 <- sim_output_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10

# Make Summary Table of output
sim_summary_10 <- sim_output_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_20 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_20 <- out_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_20 <- ggplot(data = plot_data_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20 <- list()
sim_list_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_20 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20 <- out_100_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20[[i]] <- sim_data_20
}

sim_output_20 <- bind_rows(sim_list_20)
# Summary table of endpoint data
sim_output_20 <- sim_output_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20

# Make Summary Table of output
sim_summary_20 <- sim_output_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_30 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_30 <- out_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_30 <- ggplot(data = plot_data_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30 <- list()
sim_list_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_30 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30 <- out_100_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30[[i]] <- sim_data_30
}

sim_output_30 <- bind_rows(sim_list_30)
# Summary table of endpoint data
sim_output_30 <- sim_output_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30

# Make Summary Table of output
sim_summary_30 <- sim_output_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_40 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_40 <- out_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_40 <- ggplot(data = plot_data_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40 <- list()
sim_list_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_40 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40 <- out_100_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40[[i]] <- sim_data_40
}

sim_output_40 <- bind_rows(sim_list_40)
# Summary table of endpoint data
sim_output_40 <- sim_output_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40

# Make Summary Table of output
sim_summary_40 <- sim_output_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_50 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_50 <- out_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_50 <- ggplot(data = plot_data_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50 <- list()
sim_list_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_50 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50 <- out_100_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50[[i]] <- sim_data_50
}

sim_output_50 <- bind_rows(sim_list_50)
# Summary table of endpoint data
sim_output_50 <- sim_output_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50

# Make Summary Table of output
sim_summary_50 <- sim_output_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_60 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_60 <- out_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_60 <- ggplot(data = plot_data_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60 <- list()
sim_list_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_60 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60 <- out_100_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60[[i]] <- sim_data_60
}

sim_output_60 <- bind_rows(sim_list_60)
# Summary table of endpoint data
sim_output_60 <- sim_output_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60

# Make Summary Table of output
sim_summary_60 <- sim_output_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_70 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_70 <- out_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_70 <- ggplot(data = plot_data_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70 <- list()
sim_list_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_70 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70 <- out_100_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70[[i]] <- sim_data_70
}

sim_output_70 <- bind_rows(sim_list_70)
# Summary table of endpoint data
sim_output_70 <- sim_output_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70

# Make Summary Table of output
sim_summary_70 <- sim_output_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_80 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_80 <- out_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_80 <- ggplot(data = plot_data_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80 <- list()
sim_list_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_80 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80 <- out_100_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80[[i]] <- sim_data_80
}

sim_output_80 <- bind_rows(sim_list_80)
# Summary table of endpoint data
sim_output_80 <- sim_output_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80

# Make Summary Table of output
sim_summary_80 <- sim_output_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_150 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_150 <- out_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_150 <- ggplot(data = plot_data_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150 <- list()
sim_list_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_150 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150 <- out_100_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150[[i]] <- sim_data_150
}

sim_output_150 <- bind_rows(sim_list_150)
# Summary table of endpoint data
sim_output_150 <- sim_output_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150

# Make Summary Table of output
sim_summary_150 <- sim_output_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(4)
out_100 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_180 <- out_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_180 <- ggplot(data = plot_data_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180 <- list()
sim_list_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N - initial_infected, initial_infected, 0, 0, N)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_180 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180 <- out_100_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180[[i]] <- sim_data_180
}

sim_output_180 <- bind_rows(sim_list_180)
# Summary table of endpoint data
sim_output_180 <- sim_output_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180

# Make Summary Table of output
sim_summary_180 <- sim_output_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_365 <- ssa(
  x0 = x0,
  a = a,
  nu = nu,
  parms = parms_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_365 <- out_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_365 <- ggplot(data = plot_data_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365 <- list()
sim_list_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
 N_a <-     sample(camps.data$camp_total, 1)    # Sample different patch sizes for each sim
  
  x0 <- c(N_a - initial_infected, initial_infected, 0, 0,N_a)

  names(x0) <- c("S","E","I", "R", "N")


  out_100_365 <- ssa(
    x0 = x0,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365 <- out_100_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365[[i]] <- sim_data_365
}

sim_output_365 <- bind_rows(sim_list_365)
# Summary table of endpoint data
sim_output_365 <- sim_output_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365

# Make Summary Table of output
sim_summary_365 <- sim_output_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365

Results

waning_results_single <- sim_summary %>%
  bind_rows(sim_summary_1) %>%
  bind_rows(sim_summary_3) %>%
  bind_rows(sim_summary_7) %>%
  bind_rows(sim_summary_10) %>%
  bind_rows(sim_summary_20) %>%
  bind_rows(sim_summary_30) %>%
  bind_rows(sim_summary_40) %>%
  bind_rows(sim_summary_50) %>%
  bind_rows(sim_summary_60) %>%
  bind_rows(sim_summary_70) %>%
  bind_rows(sim_summary_80) %>%
  bind_rows(sim_summary_100) %>%
  bind_rows(sim_summary_150) %>%
  bind_rows(sim_summary_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 1)

write_csv(waning_results_single, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single.csv")

waning_results_single
ggplot(waning_results_single, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

7-Patch Metapopulation Model

Recent studies have suggested that pre-agricultural hunter-gatherers did not live in small isolated groups but fromed interconnected multi-camp networks. To investigate this we built a second population that accounts for metapopulation structure of hunter-gatherers. The second model follows an almost identical format as the single population model, but instead has been expanded to accommodate the metapopulation structure of multi-band hunter-gatherer groups:

\[\begin{align*} \frac{{{\mathrm{d}}S}}{{{\mathrm{d}}t}} & = \underbrace {\mu_i N_i}_{{\mathrm{birth}}}~ - ~\underbrace {\biggl(\frac{\beta_{ii} I_i}{N_i} + \frac{\beta_{ji} I_j} {N_j} + ... \biggr)S_i}_{{\mathrm{infection}}}~~ + \underbrace {\omega_i R_i}_{{\mathrm{lost}}\,{\mathrm{immunity}}} - \underbrace {\mu_i S_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}E}}{{{\mathrm{d}}t}} & = \underbrace {\biggl(\frac{\beta_{ii} I_i}{N_i} + \frac{\beta_{ji} I_j} {N_j} + ... \biggr)S_i}_{{\mathrm{infection}}}~ - ~\underbrace {\sigma_i E_i}_{{\mathrm{latency}}} - \underbrace {\mu_i E_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}I}}{{{\mathrm{d}}t}} & = \underbrace {\sigma_i E_i}_{{\mathrm{latency}}} - \underbrace {\gamma_i I_i}_{{\mathrm{recovery}}} - ~\underbrace {\left( {\mu_i + \alpha_i } \right)I_i}_{{\mathrm{death}}} \\ \frac{{{\mathrm{d}}R}}{{{\mathrm{d}}t}} & = \underbrace {\gamma_i I_i}_{{\mathrm{recovery}}} - \underbrace {\omega_i R_i}_{{\mathrm{lost}}\ {\mathrm{immunity}}} - \underbrace {\mu_i R_i}_{{\mathrm{death}}} \end{align*}\]

These coupled differential equations describe the within-patch SEIRS-type dynamics of the \(i\)th patch where the force of infection is driven by contact of susceptibles with infecteds within the \(i\)th patch and in the \(j\)th other patches. Both models assume that compartments are well-mixed and that the waiting times between compartments are exponentially distributed.

Model Set-up

We first modeled transmission in a metapopulation of 7 camps, as observed by Migliano et al. (2023), with one initially infected individual from a randomly selected patch.

# Define Paramenters
patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Patch size
U <- length(patchPopSize)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize[i])
  }
))

names(x0_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Define functions for calculating R0 from next-generation matrix

# Calculate R0 from NGM

R0ngm <- function(nextgen_matrix) {
  eigenvalues = eigen(nextgen_matrix, only.values = T)
  R0 = max(abs(eigenvalues$values))
  return(R0)
}

beta.ngm <- function(beta_matrix) {
  eigenvalues = eigen(beta_matrix, only.values = T)
  beta_ngm = max(abs(eigenvalues$values))
  return(beta_ngm)
}

Run Metapopulation Model

#Collect parameters
parms_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_matrix[i,i] = within_pop_contact*beta*(1/parms_meta$gamma)
    parms_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_matrix[j,i] = between_pop_contact*beta*(1/parms_meta$gamma)
    nextgen_matrix[i,j] = between_pop_contact*beta*(1/parms_meta$gamma)
    parms_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_matrix[j,j] = within_pop_contact*beta*(1/parms_meta$gamma)
    beta_matrix[i,i] = within_pop_contact*beta
    beta_matrix[j,i] = between_pop_contact*beta
    beta_matrix[i,j] = between_pop_contact*beta
    beta_matrix[j,j] = within_pop_contact*beta
  }
  parms_meta[[paste0("N", i)]] = patchPopSize[i]
}
# Run simulations with the Direct method
set.seed(25)
out_meta <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_meta <- out_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta <- ggplot(data = plot_data_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_meta

ggsave(filename = "meta_plot_7.pdf", 
       plot = plot_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_meta <- out_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_meta
beta_meta <- beta.ngm(beta_matrix)
paste0("Beta for whole system = ", beta_meta)


R0_meta <- R0ngm(nextgen_matrix)
paste0("R0 = ", R0_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_meta <- as_tibble(out_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta <- list()
sim_list_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
  }
))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_meta <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta <- out_100_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta[[i]] <- sim_data_meta
}

sim_output_meta <- bind_rows(sim_list_meta)
# Summary table of endpoint data
sim_output_meta <- sim_output_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
Error in group_by(., sim) : object 'sim_output_meta' not found
# Make Summary Table of output
sim_summary_meta <- sim_output_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_meta

Varying waining immunity

0 Days

#Collect parameters
parms_meta_0 <- parms_meta
parms_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_meta_0 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_0 <- out_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_0 <- ggplot(data = plot_data_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_0 <- list()
sim_list_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_0 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_0 <- out_100_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_0[[i]] <- sim_data_meta_0
}

sim_output_meta_0 <- bind_rows(sim_list_meta_0)
# Summary table of endpoint data
sim_output_meta_0 <- sim_output_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_0

# Make Summary Table of output
sim_summary_meta_0 <- sim_output_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_meta_0

1 Day

#Collect parameters
parms_meta_1 <- parms_meta
parms_meta_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_meta_1 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_1 <- out_meta_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_1 <- ggplot(data = plot_data_meta_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_1 <- list()
sim_list_meta_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_1 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_1 <- out_100_meta_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_1[[i]] <- sim_data_meta_1
}

sim_output_meta_1 <- bind_rows(sim_list_meta_1)
# Summary table of endpoint data
sim_output_meta_1 <- sim_output_meta_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_1

# Make Summary Table of output
sim_summary_meta_1 <- sim_output_meta_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_meta_1

3 Days

#Collect parameters
parms_meta_3 <- parms_meta
parms_meta_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_meta_3 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_3 <- out_meta_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_3 <- ggplot(data = plot_data_meta_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_3 <- list()
sim_list_meta_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_3 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_3 <- out_100_meta_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_3[[i]] <- sim_data_meta_3
}

sim_output_meta_3 <- bind_rows(sim_list_meta_3)
# Summary table of endpoint data
sim_output_meta_3 <- sim_output_meta_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_3

# Make Summary Table of output
sim_summary_meta_3 <- sim_output_meta_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_meta_3

7 Days

#Collect parameters
parms_meta_7 <- parms_meta
parms_meta_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_meta_7 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_7 <- out_meta_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_7 <- ggplot(data = plot_data_meta_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_7 <- list()
sim_list_meta_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_7 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_7 <- out_100_meta_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_7[[i]] <- sim_data_meta_7
}

sim_output_meta_7 <- bind_rows(sim_list_meta_7)
# Summary table of endpoint data
sim_output_meta_7 <- sim_output_meta_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_7

# Make Summary Table of output
sim_summary_meta_7 <- sim_output_meta_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_meta_7

10 Days

#Collect parameters
parms_meta_10 <- parms_meta
parms_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_meta_10 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_10 <- out_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_10 <- ggplot(data = plot_data_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_10 <- list()
sim_list_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_10 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_10 <- out_100_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_10[[i]] <- sim_data_meta_10
}

sim_output_meta_10 <- bind_rows(sim_list_meta_10)
# Summary table of endpoint data
sim_output_meta_10 <- sim_output_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_meta_10 <- sim_output_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/14)
sim_summary_meta_10

20 Days

#Collect parameters
parms_meta_20 <- parms_meta
parms_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_meta_20 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_20 <- out_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_20 <- ggplot(data = plot_data_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_20 <- list()
sim_list_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_20 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_20 <- out_100_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_20[[i]] <- sim_data_meta_20
}

sim_output_meta_20 <- bind_rows(sim_list_meta_20)
# Summary table of endpoint data
sim_output_meta_20 <- sim_output_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_20

# Make Summary Table of output
sim_summary_meta_20 <- sim_output_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_meta_20

30 Days

#Collect parameters
parms_meta_30 <- parms_meta
parms_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_meta_30 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_30 <- out_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_30 <- ggplot(data = plot_data_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_30 <- list()
sim_list_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_30 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_30 <- out_100_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_30[[i]] <- sim_data_meta_30
}

sim_output_meta_30 <- bind_rows(sim_list_meta_30)
# Summary table of endpoint data
sim_output_meta_30 <- sim_output_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_30

# Make Summary Table of output
sim_summary_meta_30 <- sim_output_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_meta_30

40 Days

#Collect parameters
parms_meta_40 <- parms_meta
parms_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_meta_40 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_40 <- out_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_40 <- ggplot(data = plot_data_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_40 <- list()
sim_list_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_40 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_40 <- out_100_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_40[[i]] <- sim_data_meta_40
}

sim_output_meta_40 <- bind_rows(sim_list_meta_40)
# Summary table of endpoint data
sim_output_meta_40 <- sim_output_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_40

# Make Summary Table of output
sim_summary_meta_40 <- sim_output_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_meta_40

50 Days

#Collect parameters
parms_meta_50 <- parms_meta
parms_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_meta_50 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_50 <- out_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_50 <- ggplot(data = plot_data_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_50 <- list()
sim_list_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_50 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_50 <- out_100_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_50[[i]] <- sim_data_meta_50
}

sim_output_meta_50 <- bind_rows(sim_list_meta_50)
# Summary table of endpoint data
sim_output_meta_50 <- sim_output_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_50

# Make Summary Table of output
sim_summary_meta_50 <- sim_output_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_meta_50

60 Days

#Collect parameters
parms_meta_60 <- parms_meta
parms_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_meta_60 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_60 <- out_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_60 <- ggplot(data = plot_data_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_60 <- list()
sim_list_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_60 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_60 <- out_100_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_60[[i]] <- sim_data_meta_60
}

sim_output_meta_60 <- bind_rows(sim_list_meta_60)
# Summary table of endpoint data
sim_output_meta_60 <- sim_output_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_60

# Make Summary Table of output
sim_summary_meta_60 <- sim_output_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_meta_60

70 Days

#Collect parameters
parms_meta_70 <- parms_meta
parms_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_meta_70 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_70 <- out_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_70 <- ggplot(data = plot_data_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_70 <- list()
sim_list_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_70 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_70 <- out_100_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_70[[i]] <- sim_data_meta_70
}

sim_output_meta_70 <- bind_rows(sim_list_meta_70)
# Summary table of endpoint data
sim_output_meta_70 <- sim_output_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_70

# Make Summary Table of output
sim_summary_meta_70 <- sim_output_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_meta_70

80 Days

#Collect parameters
parms_meta_80 <- parms_meta
parms_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_meta_80 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_80 <- out_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_80 <- ggplot(data = plot_data_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_80 <- list()
sim_list_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_80 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_80 <- out_100_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_80[[i]] <- sim_data_meta_80
}

sim_output_meta_80 <- bind_rows(sim_list_meta_80)
# Summary table of endpoint data
sim_output_meta_80 <- sim_output_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_80

# Make Summary Table of output
sim_summary_meta_80 <- sim_output_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_meta_80

90 Days

#Collect parameters
parms_meta_90 <- parms_meta
parms_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_meta_90 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_90 <- out_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_90 <- ggplot(data = plot_data_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_90 <- list()
sim_list_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_90 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_90 <- out_100_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_90[[i]] <- sim_data_meta_90
}

sim_output_meta_90 <- bind_rows(sim_list_meta_90)
# Summary table of endpoint data
sim_output_meta_90 <- sim_output_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_90

# Make Summary Table of output
sim_summary_meta_90 <- sim_output_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_meta_90

180 Days

#Collect parameters
parms_meta_180 <- parms_meta
parms_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_meta_180 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_180 <- out_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_180 <- ggplot(data = plot_data_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_180 <- list()
sim_list_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_180 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_180 <- out_100_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_180[[i]] <- sim_data_meta_180
}

sim_output_meta_180 <- bind_rows(sim_list_meta_180)
# Summary table of endpoint data
sim_output_meta_180 <- sim_output_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_180

# Make Summary Table of output
sim_summary_meta_180 <- sim_output_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_meta_180

110 Days

#Collect parameters
parms_meta_110 <- parms_meta
parms_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_meta_110 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_110 <- out_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_110 <- ggplot(data = plot_data_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_110 <- list()
sim_list_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_110 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_110 <- out_100_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_110[[i]] <- sim_data_meta_110
}

sim_output_meta_110 <- bind_rows(sim_list_meta_110)
# Summary table of endpoint data
sim_output_meta_110 <- sim_output_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_110

# Make Summary Table of output
sim_summary_meta_110 <- sim_output_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_meta_110

120 Days

#Collect parameters
parms_meta_120 <- parms_meta
parms_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_meta_120 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_120 <- out_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_120 <- ggplot(data = plot_data_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_120 <- list()
sim_list_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_120 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_120 <- out_100_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_120[[i]] <- sim_data_meta_120
}

sim_output_meta_120 <- bind_rows(sim_list_meta_120)
# Summary table of endpoint data
sim_output_meta_120 <- sim_output_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_120

# Make Summary Table of output
sim_summary_meta_120 <- sim_output_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_meta_120

130 Days

#Collect parameters
parms_meta_130 <- parms_meta
parms_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_meta_130 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_130 <- out_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_130 <- ggplot(data = plot_data_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_130 <- list()
sim_list_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_130 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_130 <- out_100_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_130[[i]] <- sim_data_meta_130
}

sim_output_meta_130 <- bind_rows(sim_list_meta_130)
# Summary table of endpoint data
sim_output_meta_130 <- sim_output_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_130

# Make Summary Table of output
sim_summary_meta_130 <- sim_output_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_meta_130

150 Days

#Collect parameters
parms_meta_150 <- parms_meta
parms_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_meta_150 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_150 <- out_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_150 <- ggplot(data = plot_data_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_150 <- list()
sim_list_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_150 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_150 <- out_100_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_150[[i]] <- sim_data_meta_150
}

sim_output_meta_150 <- bind_rows(sim_list_meta_150)
# Summary table of endpoint data
sim_output_meta_150 <- sim_output_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_150

# Make Summary Table of output
sim_summary_meta_150 <- sim_output_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_meta_150

220 Days

#Collect parameters
parms_meta_220 <- parms_meta
parms_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_meta_220 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_220 <- out_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_220 <- ggplot(data = plot_data_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_220 <- list()
sim_list_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_220 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_220 <- out_100_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_220[[i]] <- sim_data_meta_220
}

sim_output_meta_220 <- bind_rows(sim_list_meta_220)
# Summary table of endpoint data
sim_output_meta_220 <- sim_output_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_220

# Make Summary Table of output
sim_summary_meta_220 <- sim_output_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_meta_220

270 Days

#Collect parameters
parms_meta_270 <- parms_meta
parms_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_meta_270 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_270 <- out_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_270 <- ggplot(data = plot_data_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_270 <- list()
sim_list_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_270 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_270 <- out_100_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_270[[i]] <- sim_data_meta_270
}

sim_output_meta_270 <- bind_rows(sim_list_meta_270)
# Summary table of endpoint data
sim_output_meta_270 <- sim_output_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_270

# Make Summary Table of output
sim_summary_meta_270 <- sim_output_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_meta_270

365 Days

#Collect parameters
parms_meta_365 <- parms_meta
parms_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_meta_365 <- ssa(
  x0 = x0_meta,
  a = a_meta,
  nu = nu_meta,
  parms = parms_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_meta_365 <- out_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_meta_365 <- ggplot(data = plot_data_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_meta_365 <- list()
sim_list_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize[x])
          }
        ))

names(x0_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_meta_365 <- ssa(
    x0 = x0_meta,
    a = a_meta,
    nu = nu_meta,
    parms = parms_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_meta_365 <- out_100_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_meta_365[[i]] <- sim_data_meta_365
}

sim_output_meta_365 <- bind_rows(sim_list_meta_365)
# Summary table of endpoint data
sim_output_meta_365 <- sim_output_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_meta_365

# Make Summary Table of output
sim_summary_meta_365 <- sim_output_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_meta_365

Single

Results

waning_results_7 <- sim_summary_meta %>%
  bind_rows(sim_summary_meta_3) %>%
  bind_rows(sim_summary_meta_7) %>%
  bind_rows(sim_summary_meta_10) %>%
  bind_rows(sim_summary_meta_20) %>%
  bind_rows(sim_summary_meta_30) %>%
  bind_rows(sim_summary_meta_40) %>%
  bind_rows(sim_summary_meta_50) %>%
  bind_rows(sim_summary_meta_60) %>%
  bind_rows(sim_summary_meta_70) %>%
  bind_rows(sim_summary_meta_80) %>%
  bind_rows(sim_summary_meta_90) %>%
  bind_rows(sim_summary_meta_100) %>%
  bind_rows(sim_summary_meta_110) %>%
  bind_rows(sim_summary_meta_120) %>%
  bind_rows(sim_summary_meta_130) %>%
  bind_rows(sim_summary_meta_150) %>%
  bind_rows(sim_summary_meta_220) %>%
  bind_rows(sim_summary_meta_270) %>%
  bind_rows(sim_summary_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 7)

write_csv(waning_results_7, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_7.csv")

waning_results_7
ggplot(waning_results_7, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

3-Patch Metapopulation Model

The same metapopulation SEIRS model was then used to model the dynamics of persistence in a 3-patch system and understand the effect of waning immunity.

###Set-up

# Define Paramenters
patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Patch size
U <- length(patchPopSize_3)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_3_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize_3[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize_3[i])
  }
))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_3_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_3_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Run Metapopulation Model

#Collect parameters
parms_3_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_3_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_3_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_3_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_3_matrix[i,i] = within_pop_contact*beta*(1/parms_3_meta$gamma)
    parms_3_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_3_matrix[j,i] = between_pop_contact*beta*(1/parms_3_meta$gamma)
    nextgen_3_matrix[i,j] = between_pop_contact*beta*(1/parms_3_meta$gamma)
    parms_3_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_3_matrix[j,j] = within_pop_contact*beta*(1/parms_3_meta$gamma)
    beta_3_matrix[i,i] = within_pop_contact*beta
    beta_3_matrix[j,i] = between_pop_contact*beta
    beta_3_matrix[i,j] = between_pop_contact*beta
    beta_3_matrix[j,j] = within_pop_contact*beta
  }
  parms_3_meta[[paste0("N", i)]] = patchPopSize_3[i]
}
# Run simulations with the Direct method
set.seed(25)
out_3_meta <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_3_meta <- out_3_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta <- ggplot(data = plot_data_3_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 1, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_3_meta

ggsave(filename = "meta_plot_3.pdf", 
       plot = plot_3_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_3_meta <- out_3_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_3_meta
beta_3_meta <- beta.ngm(beta_3_matrix)
paste0("Beta for whole system = ", beta_3_meta)


R0_3_meta <- R0ngm(nextgen_3_matrix)
paste0("R0 = ", R0_3_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_3_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_3_meta <- as_tibble(out_3_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_3_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta <- list()
sim_list_3_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 7, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
  }
))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_3_meta <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta <- out_100_3_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta[[i]] <- sim_data_3_meta
}

sim_output_3_meta <- bind_rows(sim_list_3_meta)
# Summary table of endpoint data
sim_output_3_meta <- sim_output_3_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta
# Make Summary Table of output
sim_summary_3_meta <- sim_output_3_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_3_meta

Varying waining immunity

0 Days

#Collect parameters
parms_3_meta_0 <- parms_3_meta
parms_3_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_3_meta_0 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_0 <- out_3_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_0 <- ggplot(data = plot_data_3_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_0 <- list()
sim_list_3_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_0 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_0 <- out_100_3_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_0[[i]] <- sim_data_3_meta_0
}

sim_output_3_meta_0 <- bind_rows(sim_list_3_meta_0)
# Summary table of endpoint data
sim_output_3_meta_0 <- sim_output_3_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_0

# Make Summary Table of output
sim_summary_3_meta_0 <- sim_output_3_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_3_meta_0

1 Day

#Collect parameters
parms_3_meta_1 <- parms_3_meta
parms_3_meta_1$omega <- 1


# Run simulations with the Direct method
set.seed(4)
out_3_meta_1 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_1,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_1 <- out_3_meta_1$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_1 <- ggplot(data = plot_data_3_meta_1, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_1
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_1 <- list()
sim_list_3_meta_1 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_1 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_1 <- out_100_3_meta_1$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_1[[i]] <- sim_data_3_meta_1
}

sim_output_3_meta_1 <- bind_rows(sim_list_3_meta_1)
# Summary table of endpoint data
sim_output_3_meta_1 <- sim_output_3_meta_1 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_1

# Make Summary Table of output
sim_summary_3_meta_1 <- sim_output_3_meta_1 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_3_meta_1

3 Days

#Collect parameters
parms_3_meta_3 <- parms_3_meta
parms_3_meta_3$omega <- 1/3


# Run simulations with the Direct method
set.seed(4)
out_3_meta_3 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_3,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_3 <- out_3_meta_3$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_3 <- ggplot(data = plot_data_3_meta_3, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_3
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_3 <- list()
sim_list_3_meta_3 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_3 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_3 <- out_100_3_meta_3$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_3[[i]] <- sim_data_3_meta_3
}

sim_output_3_meta_3 <- bind_rows(sim_list_3_meta_3)
# Summary table of endpoint data
sim_output_3_meta_3 <- sim_output_3_meta_3 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_3

# Make Summary Table of output
sim_summary_3_meta_3 <- sim_output_3_meta_3 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_meta_3

7 Days

#Collect parameters
parms_3_meta_7 <- parms_3_meta
parms_3_meta_7$omega <- 1/7


# Run simulations with the Direct method
set.seed(4)
out_3_meta_7 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_7,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_7 <- out_3_meta_7$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_7 <- ggplot(data = plot_data_3_meta_7, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_7
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_7 <- list()
sim_list_3_meta_7 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_7 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_7 <- out_100_3_meta_7$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_7[[i]] <- sim_data_3_meta_7
}

sim_output_3_meta_7 <- bind_rows(sim_list_3_meta_7)
# Summary table of endpoint data
sim_output_3_meta_7 <- sim_output_3_meta_7 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_7

# Make Summary Table of output
sim_summary_3_meta_7 <- sim_output_3_meta_7 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_3_meta_7

10 Days

#Collect parameters
parms_3_meta_10 <- parms_3_meta
parms_3_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_3_meta_10 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_10 <- out_3_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_10 <- ggplot(data = plot_data_3_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_10 <- list()
sim_list_3_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_10 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_10 <- out_100_3_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_10[[i]] <- sim_data_3_meta_10
}

sim_output_3_meta_10 <- bind_rows(sim_list_3_meta_10)
# Summary table of endpoint data
sim_output_3_meta_10 <- sim_output_3_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_3_meta_10 <- sim_output_3_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/14)
sim_summary_3_meta_10

20 Days

#Collect parameters
parms_3_meta_20 <- parms_3_meta
parms_3_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_3_meta_20 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_20 <- out_3_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_20 <- ggplot(data = plot_data_3_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_20 <- list()
sim_list_3_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_20 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_20 <- out_100_3_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_20[[i]] <- sim_data_3_meta_20
}

sim_output_3_meta_20 <- bind_rows(sim_list_3_meta_20)
# Summary table of endpoint data
sim_output_3_meta_20 <- sim_output_3_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_20

# Make Summary Table of output
sim_summary_3_meta_20 <- sim_output_3_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_3_meta_20

30 Days

#Collect parameters
parms_3_meta_30 <- parms_3_meta
parms_3_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_3_meta_30 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_30 <- out_3_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_30 <- ggplot(data = plot_data_3_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_30 <- list()
sim_list_3_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_30 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_30 <- out_100_3_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_30[[i]] <- sim_data_3_meta_30
}

sim_output_3_meta_30 <- bind_rows(sim_list_3_meta_30)
# Summary table of endpoint data
sim_output_3_meta_30 <- sim_output_3_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_30

# Make Summary Table of output
sim_summary_3_meta_30 <- sim_output_3_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_3_meta_30

40 Days

#Collect parameters
parms_3_meta_40 <- parms_3_meta
parms_3_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_3_meta_40 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_40 <- out_3_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_40 <- ggplot(data = plot_data_3_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_40 <- list()
sim_list_3_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_40 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_40 <- out_100_3_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_40[[i]] <- sim_data_3_meta_40
}

sim_output_3_meta_40 <- bind_rows(sim_list_3_meta_40)
# Summary table of endpoint data
sim_output_3_meta_40 <- sim_output_3_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_40

# Make Summary Table of output
sim_summary_3_meta_40 <- sim_output_3_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_3_meta_40

50 Days

#Collect parameters
parms_3_meta_50 <- parms_3_meta
parms_3_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_3_meta_50 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_50 <- out_3_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_50 <- ggplot(data = plot_data_3_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_50 <- list()
sim_list_3_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_50 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_50 <- out_100_3_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_50[[i]] <- sim_data_3_meta_50
}

sim_output_3_meta_50 <- bind_rows(sim_list_3_meta_50)
# Summary table of endpoint data
sim_output_3_meta_50 <- sim_output_3_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_50

# Make Summary Table of output
sim_summary_3_meta_50 <- sim_output_3_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_3_meta_50

60 Days

#Collect parameters
parms_3_meta_60 <- parms_3_meta
parms_3_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_3_meta_60 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_60 <- out_3_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_60 <- ggplot(data = plot_data_3_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_60 <- list()
sim_list_3_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_60 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_60 <- out_100_3_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_60[[i]] <- sim_data_3_meta_60
}

sim_output_3_meta_60 <- bind_rows(sim_list_3_meta_60)
# Summary table of endpoint data
sim_output_3_meta_60 <- sim_output_3_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_60

# Make Summary Table of output
sim_summary_3_meta_60 <- sim_output_3_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_3_meta_60

70 Days

#Collect parameters
parms_3_meta_70 <- parms_3_meta
parms_3_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_3_meta_70 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_70 <- out_3_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_70 <- ggplot(data = plot_data_3_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_70 <- list()
sim_list_3_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_70 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_70 <- out_100_3_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_70[[i]] <- sim_data_3_meta_70
}

sim_output_3_meta_70 <- bind_rows(sim_list_3_meta_70)
# Summary table of endpoint data
sim_output_3_meta_70 <- sim_output_3_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_70

# Make Summary Table of output
sim_summary_3_meta_70 <- sim_output_3_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_3_meta_70

80 Days

#Collect parameters
parms_3_meta_80 <- parms_3_meta
parms_3_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_3_meta_80 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_80 <- out_3_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_80 <- ggplot(data = plot_data_3_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_80 <- list()
sim_list_3_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_80 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_80 <- out_100_3_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_80[[i]] <- sim_data_3_meta_80
}

sim_output_3_meta_80 <- bind_rows(sim_list_3_meta_80)
# Summary table of endpoint data
sim_output_3_meta_80 <- sim_output_3_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_80

# Make Summary Table of output
sim_summary_3_meta_80 <- sim_output_3_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_3_meta_80

90 Days

#Collect parameters
parms_3_meta_90 <- parms_3_meta
parms_3_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_3_meta_90 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_90 <- out_3_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_90 <- ggplot(data = plot_data_3_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_90 <- list()
sim_list_3_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_90 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_90 <- out_100_3_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_90[[i]] <- sim_data_3_meta_90
}

sim_output_3_meta_90 <- bind_rows(sim_list_3_meta_90)
# Summary table of endpoint data
sim_output_3_meta_90 <- sim_output_3_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_90

# Make Summary Table of output
sim_summary_3_meta_90 <- sim_output_3_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_3_meta_90

180 Days

#Collect parameters
parms_3_meta_180 <- parms_3_meta
parms_3_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_3_meta_180 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_180 <- out_3_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_180 <- ggplot(data = plot_data_3_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_180 <- list()
sim_list_3_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_180 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_180 <- out_100_3_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_180[[i]] <- sim_data_3_meta_180
}

sim_output_3_meta_180 <- bind_rows(sim_list_3_meta_180)
# Summary table of endpoint data
sim_output_3_meta_180 <- sim_output_3_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_180

# Make Summary Table of output
sim_summary_3_meta_180 <- sim_output_3_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_3_meta_180

110 Days

#Collect parameters
parms_3_meta_110 <- parms_3_meta
parms_3_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_3_meta_110 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_110 <- out_3_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_110 <- ggplot(data = plot_data_3_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_110 <- list()
sim_list_3_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_110 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_110 <- out_100_3_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_110[[i]] <- sim_data_3_meta_110
}

sim_output_3_meta_110 <- bind_rows(sim_list_3_meta_110)
# Summary table of endpoint data
sim_output_3_meta_110 <- sim_output_3_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_110

# Make Summary Table of output
sim_summary_3_meta_110 <- sim_output_3_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_3_meta_110

120 Days

#Collect parameters
parms_3_meta_120 <- parms_3_meta
parms_3_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_3_meta_120 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_120 <- out_3_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_120 <- ggplot(data = plot_data_3_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_120 <- list()
sim_list_3_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_120 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_120 <- out_100_3_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_120[[i]] <- sim_data_3_meta_120
}

sim_output_3_meta_120 <- bind_rows(sim_list_3_meta_120)
# Summary table of endpoint data
sim_output_3_meta_120 <- sim_output_3_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_120

# Make Summary Table of output
sim_summary_3_meta_120 <- sim_output_3_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_3_meta_120

130 Days

#Collect parameters
parms_3_meta_130 <- parms_3_meta
parms_3_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_3_meta_130 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_130 <- out_3_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_130 <- ggplot(data = plot_data_3_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_130 <- list()
sim_list_3_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_130 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_130 <- out_100_3_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_130[[i]] <- sim_data_3_meta_130
}

sim_output_3_meta_130 <- bind_rows(sim_list_3_meta_130)
# Summary table of endpoint data
sim_output_3_meta_130 <- sim_output_3_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_130

# Make Summary Table of output
sim_summary_3_meta_130 <- sim_output_3_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_3_meta_130

150 Days

#Collect parameters
parms_3_meta_150 <- parms_3_meta
parms_3_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_3_meta_150 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_150 <- out_3_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_150 <- ggplot(data = plot_data_3_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_150 <- list()
sim_list_3_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_150 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_150 <- out_100_3_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_150[[i]] <- sim_data_3_meta_150
}

sim_output_3_meta_150 <- bind_rows(sim_list_3_meta_150)
# Summary table of endpoint data
sim_output_3_meta_150 <- sim_output_3_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_150

# Make Summary Table of output
sim_summary_3_meta_150 <- sim_output_3_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_3_meta_150

220 Days

#Collect parameters
parms_3_meta_220 <- parms_3_meta
parms_3_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_3_meta_220 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_220 <- out_3_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_220 <- ggplot(data = plot_data_3_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_220 <- list()
sim_list_3_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_220 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_220 <- out_100_3_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_220[[i]] <- sim_data_3_meta_220
}

sim_output_3_meta_220 <- bind_rows(sim_list_3_meta_220)
# Summary table of endpoint data
sim_output_3_meta_220 <- sim_output_3_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_220

# Make Summary Table of output
sim_summary_3_meta_220 <- sim_output_3_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_3_meta_220

270 Days

#Collect parameters
parms_3_meta_270 <- parms_3_meta
parms_3_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_3_meta_270 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_270 <- out_3_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_270 <- ggplot(data = plot_data_3_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_270 <- list()
sim_list_3_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_270 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_270 <- out_100_3_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_270[[i]] <- sim_data_3_meta_270
}

sim_output_3_meta_270 <- bind_rows(sim_list_3_meta_270)
# Summary table of endpoint data
sim_output_3_meta_270 <- sim_output_3_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_270

# Make Summary Table of output
sim_summary_3_meta_270 <- sim_output_3_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_3_meta_270

365 Days

#Collect parameters
parms_3_meta_365 <- parms_3_meta
parms_3_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_3_meta_365 <- ssa(
  x0 = x0_3_meta,
  a = a_3_meta,
  nu = nu_3_meta,
  parms = parms_3_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_3_meta_365 <- out_3_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_3_meta_365 <- ggplot(data = plot_data_3_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_3_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_meta_365 <- list()
sim_list_3_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 3, replace = TRUE)    # Sample different patch sizes for each sim
  x0_3_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_3_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_3_meta_365 <- ssa(
    x0 = x0_3_meta,
    a = a_3_meta,
    nu = nu_3_meta,
    parms = parms_3_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_meta_365 <- out_100_3_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_3_meta_365[[i]] <- sim_data_3_meta_365
}

sim_output_3_meta_365 <- bind_rows(sim_list_3_meta_365)
# Summary table of endpoint data
sim_output_3_meta_365 <- sim_output_3_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_meta_365

# Make Summary Table of output
sim_summary_3_meta_365 <- sim_output_3_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_3_meta_365

Results

waning_results_3 <- sim_summary_3_meta %>%
  bind_rows(sim_summary_3_meta_3) %>%
  bind_rows(sim_summary_3_meta_7) %>%
  bind_rows(sim_summary_3_meta_10) %>%
  bind_rows(sim_summary_3_meta_20) %>%
  bind_rows(sim_summary_3_meta_30) %>%
  bind_rows(sim_summary_3_meta_40) %>%
  bind_rows(sim_summary_3_meta_50) %>%
  bind_rows(sim_summary_3_meta_60) %>%
  bind_rows(sim_summary_3_meta_70) %>%
  bind_rows(sim_summary_3_meta_80) %>%
  bind_rows(sim_summary_3_meta_90) %>%
  bind_rows(sim_summary_3_meta_180) %>%
  bind_rows(sim_summary_3_meta_110) %>%
  bind_rows(sim_summary_3_meta_120) %>%
  bind_rows(sim_summary_3_meta_130) %>%
  bind_rows(sim_summary_3_meta_150) %>%
  bind_rows(sim_summary_3_meta_220) %>%
  bind_rows(sim_summary_3_meta_270) %>%
  bind_rows(sim_summary_3_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 3)

write_csv(waning_results_3, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_3.csv")

waning_results_3
ggplot(waning_results_3, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

14 Metapopulation Model

The same metapopulation SEIRS model was then used to model the dynamics of persistence in a 14-patch system and understand the effect of waning immunity.

###Set-up

# Define Paramenters
patchPopSize_14 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Patch size
U <- length(patchPopSize_14)                    # Number of patches
initial_infected <-  as.vector(rmultinom(1, 1, rep(0.5, U)))   # Initial infected (initial infected patch randomly generated)
initial_infected_patch <- which(initial_infected > 0)
simName <- "SIRS metapopulation model"       # Simulation name
tf <- 365*3                                   # Final time

# Agta Hunter-Gatherer contact rates
within_pop_contact = 1
between_pop_contact = 0.5/U     # normalised by number of patches 

#Create the named initial state vector for the U-patch system.

x0_14_meta <- unlist(lapply(
  seq_len(U), 
  function(i){ 
    c(patchPopSize_14[i] - initial_infected[i], initial_infected[i], 0, 0, patchPopSize_14[i])
  }
))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(i) paste0(c("S","E","I", "R", "N"), i)))


# Define the state change matrix for a single patch
nu_14_meta <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                     +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                      0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                      0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                      0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
# Mass-action
a_14_meta <-
  unlist(lapply(
    seq_len(U),
    function(patch) {
      i <- patch
      patches <- 1:U
      #j <- if (patch == 1) U else patch - 1
      other_patches <- patches[-i]
      patch_beta <- c()
      for(k in (1:(U-1))){
        patch_beta[k] = paste0("+(beta_", other_patches[k],i, "*I", other_patches[k], "/N", other_patches[k], ")*S", i)
      }
      c(
        paste0("(beta_", i, i, "*I", i,"/N", i, ")*S",i, paste0(patch_beta, collapse="")), # Infection
        paste0("sigma*E", i),                                       # Becomes infecious
        paste0("gamma*I", i),                                       # Recovery from infection
        paste0("omega*R", i),       # Loss of immunity
        paste0("mu*N", i),                             # Births
        paste0("mu*S", i),                                             # Deaths (S)
        paste0("mu*E", i),                                             # Deaths (E)
        paste0("mu*I", i),                                             # Deaths (I)
        paste0("mu*R", i),                                             # Deaths (R)
        paste0("alpha*I", i)                                           # Deaths from infection
        
      )
    }
  ))

Run Metapopulation Model

#Collect parameters
parms_14_meta <- list(
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

# Define transmission terms and populate next-generation matrix
beta <- 0.6

nextgen_14_matrix <- matrix(nrow = U, ncol = U, data = 0)
beta_14_matrix <- matrix(nrow = U, ncol = U, data = 0)


for(i in 1:U){
  for(j in 1:U){
    parms_14_meta[[paste0("beta_",i,i)]] = within_pop_contact*beta
    nextgen_14_matrix[i,i] = within_pop_contact*beta*(1/parms_14_meta$gamma)
    parms_14_meta[[paste0("beta_",j,i)]] = between_pop_contact*beta
    nextgen_14_matrix[j,i] = between_pop_contact*beta*(1/parms_14_meta$gamma)
    nextgen_14_matrix[i,j] = between_pop_contact*beta*(1/parms_14_meta$gamma)
    parms_14_meta[[paste0("beta_",j,j)]] = within_pop_contact*beta
    nextgen_14_matrix[j,j] = within_pop_contact*beta*(1/parms_14_meta$gamma)
    beta_14_matrix[i,i] = within_pop_contact*beta
    beta_14_matrix[j,i] = between_pop_contact*beta
    beta_14_matrix[i,j] = between_pop_contact*beta
    beta_14_matrix[j,j] = within_pop_contact*beta
  }
  parms_14_meta[[paste0("N", i)]] = patchPopSize_14[i]
}
# Run simulations with the Direct method
set.seed(25)
out_14_meta <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Plot
plot_data_14_meta <- out_14_meta$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta <- ggplot(data = plot_data_14_meta, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time (Days)",
       y="Number of Individuals",
       colour="State")+
  theme_bw()
plot_14_meta

ggsave(filename = "meta_14_plot.pdf", 
       plot = plot_14_meta,
       device = "pdf",
       width = 7, 
       height = 8,
       path = "/Users/matthewhoyle/Github_R_projects/Plots/Hunter_Gatherer_models")
## Table showing extinction/transmission info for each patch

extinct_data_14_meta <- out_14_meta$data %>%
  as_tibble() %>%
  slice_max(t) %>%
  distinct() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N")),
         persist = case_when(state=="I" & count > 0 ~ T, 
                             state=="I" & count == 0 ~ F)) %>%
  drop_na() %>%
  select(patch, count, persist)
extinct_data_14_meta
beta_14_meta <- beta.ngm(beta_14_matrix)
paste0("Beta for whole system = ", beta_14_meta)


R0_14_meta <- R0ngm(nextgen_14_matrix)
paste0("R0 = ", R0_14_meta)


paste0("Actual number of infecteds at end of sim = ", sum(extinct_data_14_meta$count))
 # Total number of infecteds at the end of sim across all patches

sim_endpoint_14_meta <- as_tibble(out_14_meta$data) %>%
  slice_max(t) %>%
  distinct()


paste0("Did simulation run reach final endpoint?")
if (sim_endpoint_14_meta$t >= tf) {
  print("Yes")
} else {
  print("No")}
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta <- list()
sim_list_14_meta <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_14 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(lapply(
  seq_len(U), 
  function(x){ 
    c(patchPopSize_14[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_14[x])
  }
))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))
  
  out_100_14_meta <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta <- out_100_14_meta$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta[[i]] <- sim_data_14_meta
}

sim_output_14_meta <- bind_rows(sim_list_14_meta)
# Summary table of endpoint data
sim_output_14_meta <- sim_output_14_meta %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta
# Make Summary Table of output
sim_summary_14_meta <- sim_output_14_meta %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_14_meta

Varying waining immunity

0 Days

#Collect parameters
parms_14_meta_0 <- parms_14_meta
parms_14_meta_0$omega <- 0


# Run simulations with the Direct method
set.seed(4)
out_14_meta_0 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_0,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_0 <- out_14_meta_0$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_0 <- ggplot(data = plot_data_14_meta_0, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_0
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_0 <- list()
sim_list_14_meta_0 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_0 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_0 <- out_100_14_meta_0$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_0[[i]] <- sim_data_14_meta_0
}

sim_output_14_meta_0 <- bind_rows(sim_list_14_meta_0)
# Summary table of endpoint data
sim_output_14_meta_0 <- sim_output_14_meta_0 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_0

# Make Summary Table of output
sim_summary_14_meta_0 <- sim_output_14_meta_0 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_14_meta_0

10 Days

#Collect parameters
parms_14_meta_10 <- parms_14_meta
parms_14_meta_10$omega <- 1/10

# Run simulations with the Direct method
set.seed(4)
out_14_meta_10 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_10,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_10 <- out_14_meta_10$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_10 <- ggplot(data = plot_data_14_meta_10, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_10
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_10 <- list()
sim_list_14_meta_10 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_10 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_10 <- out_100_14_meta_10$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_10[[i]] <- sim_data_14_meta_10
}

sim_output_14_meta_10 <- bind_rows(sim_list_14_meta_10)
# Summary table of endpoint data
sim_output_14_meta_10 <- sim_output_14_meta_10 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))

# Make Summary Table of output
sim_summary_14_meta_10 <- sim_output_14_meta_10 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_14_meta_10

20 Days

#Collect parameters
parms_14_meta_20 <- parms_14_meta
parms_14_meta_20$omega <- 1/20


# Run simulations with the Direct method
set.seed(4)
out_14_meta_20 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_20,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_20 <- out_14_meta_20$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_20 <- ggplot(data = plot_data_14_meta_20, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_20
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_20 <- list()
sim_list_14_meta_20 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_20 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_20 <- out_100_14_meta_20$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_20[[i]] <- sim_data_14_meta_20
}

sim_output_14_meta_20 <- bind_rows(sim_list_14_meta_20)
# Summary table of endpoint data
sim_output_14_meta_20 <- sim_output_14_meta_20 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_20

# Make Summary Table of output
sim_summary_14_meta_20 <- sim_output_14_meta_20 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_14_meta_20

30 Days

#Collect parameters
parms_14_meta_30 <- parms_14_meta
parms_14_meta_30$omega <- 1/30


# Run simulations with the Direct method
set.seed(4)
out_14_meta_30 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_30,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_30 <- out_14_meta_30$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_30 <- ggplot(data = plot_data_14_meta_30, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_30
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_30 <- list()
sim_list_14_meta_30 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_30 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_30 <- out_100_14_meta_30$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_30[[i]] <- sim_data_14_meta_30
}

sim_output_14_meta_30 <- bind_rows(sim_list_14_meta_30)
# Summary table of endpoint data
sim_output_14_meta_30 <- sim_output_14_meta_30 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_30

# Make Summary Table of output
sim_summary_14_meta_30 <- sim_output_14_meta_30 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_14_meta_30

40 Days

#Collect parameters
parms_14_meta_40 <- parms_14_meta
parms_14_meta_40$omega <- 1/40


# Run simulations with the Direct method
set.seed(4)
out_14_meta_40 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_40,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_40 <- out_14_meta_40$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_40 <- ggplot(data = plot_data_14_meta_40, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_40
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_40 <- list()
sim_list_14_meta_40 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_40 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_40 <- out_100_14_meta_40$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_40[[i]] <- sim_data_14_meta_40
}

sim_output_14_meta_40 <- bind_rows(sim_list_14_meta_40)
# Summary table of endpoint data
sim_output_14_meta_40 <- sim_output_14_meta_40 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_40

# Make Summary Table of output
sim_summary_14_meta_40 <- sim_output_14_meta_40 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_14_meta_40

50 Days

#Collect parameters
parms_14_meta_50 <- parms_14_meta
parms_14_meta_50$omega <- 1/50


# Run simulations with the Direct method
set.seed(4)
out_14_meta_50 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_50,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_50 <- out_14_meta_50$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_50 <- ggplot(data = plot_data_14_meta_50, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_50
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_50 <- list()
sim_list_14_meta_50 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_50 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_50 <- out_100_14_meta_50$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_50[[i]] <- sim_data_14_meta_50
}

sim_output_14_meta_50 <- bind_rows(sim_list_14_meta_50)
# Summary table of endpoint data
sim_output_14_meta_50 <- sim_output_14_meta_50 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_50

# Make Summary Table of output
sim_summary_14_meta_50 <- sim_output_14_meta_50 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_14_meta_50

60 Days

#Collect parameters
parms_14_meta_60 <- parms_14_meta
parms_14_meta_60$omega <- 1/60


# Run simulations with the Direct method
set.seed(4)
out_14_meta_60 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_60,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_60 <- out_14_meta_60$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_60 <- ggplot(data = plot_data_14_meta_60, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_60
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_60 <- list()
sim_list_14_meta_60 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_60 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_60 <- out_100_14_meta_60$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_60[[i]] <- sim_data_14_meta_60
}

sim_output_14_meta_60 <- bind_rows(sim_list_14_meta_60)
# Summary table of endpoint data
sim_output_14_meta_60 <- sim_output_14_meta_60 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_60

# Make Summary Table of output
sim_summary_14_meta_60 <- sim_output_14_meta_60 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_14_meta_60

70 Days

#Collect parameters
parms_14_meta_70 <- parms_14_meta
parms_14_meta_70$omega <- 1/70


# Run simulations with the Direct method
set.seed(4)
out_14_meta_70 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_70,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_70 <- out_14_meta_70$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_70 <- ggplot(data = plot_data_14_meta_70, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_70
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_70 <- list()
sim_list_14_meta_70 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_70 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_70 <- out_100_14_meta_70$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_70[[i]] <- sim_data_14_meta_70
}

sim_output_14_meta_70 <- bind_rows(sim_list_14_meta_70)
# Summary table of endpoint data
sim_output_14_meta_70 <- sim_output_14_meta_70 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_70

# Make Summary Table of output
sim_summary_14_meta_70 <- sim_output_14_meta_70 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_14_meta_70

80 Days

#Collect parameters
parms_14_meta_80 <- parms_14_meta
parms_14_meta_80$omega <- 1/80


# Run simulations with the Direct method
set.seed(4)
out_14_meta_80 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_80,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_80 <- out_14_meta_80$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_80 <- ggplot(data = plot_data_14_meta_80, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_80
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_80 <- list()
sim_list_14_meta_80 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_80 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_80 <- out_100_14_meta_80$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_80[[i]] <- sim_data_14_meta_80
}

sim_output_14_meta_80 <- bind_rows(sim_list_14_meta_80)
# Summary table of endpoint data
sim_output_14_meta_80 <- sim_output_14_meta_80 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_80

# Make Summary Table of output
sim_summary_14_meta_80 <- sim_output_14_meta_80 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_14_meta_80

90 Days

#Collect parameters
parms_14_meta_90 <- parms_14_meta
parms_14_meta_90$omega <- 1/90


# Run simulations with the Direct method
set.seed(4)
out_14_meta_90 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_90,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_90 <- out_14_meta_90$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_90 <- ggplot(data = plot_data_14_meta_90, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_90
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_90 <- list()
sim_list_14_meta_90 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_90 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_90 <- out_100_14_meta_90$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_90[[i]] <- sim_data_14_meta_90
}

sim_output_14_meta_90 <- bind_rows(sim_list_14_meta_90)
# Summary table of endpoint data
sim_output_14_meta_90 <- sim_output_14_meta_90 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_90

# Make Summary Table of output
sim_summary_14_meta_90 <- sim_output_14_meta_90 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_14_meta_90

180 Days

#Collect parameters
parms_14_meta_180 <- parms_14_meta
parms_14_meta_180$omega <- 1/180


# Run simulations with the Direct method
set.seed(20)
out_14_meta_180 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_180,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_180 <- out_14_meta_180$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_180 <- ggplot(data = plot_data_14_meta_180, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_180
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_180 <- list()
sim_list_14_meta_180 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_180 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_180 <- out_100_14_meta_180$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_180[[i]] <- sim_data_14_meta_180
}

sim_output_14_meta_180 <- bind_rows(sim_list_14_meta_180)
# Summary table of endpoint data
sim_output_14_meta_180 <- sim_output_14_meta_180 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_180

# Make Summary Table of output
sim_summary_14_meta_180 <- sim_output_14_meta_180 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_14_meta_180

110 Days

#Collect parameters
parms_14_meta_110 <- parms_14_meta
parms_14_meta_110$omega <- 1/110


# Run simulations with the Direct method
set.seed(4)
out_14_meta_110 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_110,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_110 <- out_14_meta_110$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_110 <- ggplot(data = plot_data_14_meta_110, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_110
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_110 <- list()
sim_list_14_meta_110 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_110 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_110 <- out_100_14_meta_110$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_110[[i]] <- sim_data_14_meta_110
}

sim_output_14_meta_110 <- bind_rows(sim_list_14_meta_110)
# Summary table of endpoint data
sim_output_14_meta_110 <- sim_output_14_meta_110 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_110

# Make Summary Table of output
sim_summary_14_meta_110 <- sim_output_14_meta_110 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_14_meta_110

120 Days

#Collect parameters
parms_14_meta_120 <- parms_14_meta
parms_14_meta_120$omega <- 1/120


# Run simulations with the Direct method
set.seed(4)
out_14_meta_120 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_120,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_120 <- out_14_meta_120$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_120 <- ggplot(data = plot_data_14_meta_120, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_120
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_120 <- list()
sim_list_14_meta_120 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_120 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_120 <- out_100_14_meta_120$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_120[[i]] <- sim_data_14_meta_120
}

sim_output_14_meta_120 <- bind_rows(sim_list_14_meta_120)
# Summary table of endpoint data
sim_output_14_meta_120 <- sim_output_14_meta_120 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_120

# Make Summary Table of output
sim_summary_14_meta_120 <- sim_output_14_meta_120 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_14_meta_120

130 Days

#Collect parameters
parms_14_meta_130 <- parms_14_meta
parms_14_meta_130$omega <- 1/130


# Run simulations with the Direct method
set.seed(4)
out_14_meta_130 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_130,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_130 <- out_14_meta_130$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_130 <- ggplot(data = plot_data_14_meta_130, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_130
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_130 <- list()
sim_list_14_meta_130 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_130 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_130 <- out_100_14_meta_130$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_130[[i]] <- sim_data_14_meta_130
}

sim_output_14_meta_130 <- bind_rows(sim_list_14_meta_130)
# Summary table of endpoint data
sim_output_14_meta_130 <- sim_output_14_meta_130 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_130

# Make Summary Table of output
sim_summary_14_meta_130 <- sim_output_14_meta_130 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_14_meta_130

150 Days

#Collect parameters
parms_14_meta_150 <- parms_14_meta
parms_14_meta_150$omega <- 1/150


# Run simulations with the Direct method
set.seed(4)
out_14_meta_150 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_150,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_150 <- out_14_meta_150$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_150 <- ggplot(data = plot_data_14_meta_150, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_150
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_150 <- list()
sim_list_14_meta_150 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_150 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_150 <- out_100_14_meta_150$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_150[[i]] <- sim_data_14_meta_150
}

sim_output_14_meta_150 <- bind_rows(sim_list_14_meta_150)
# Summary table of endpoint data
sim_output_14_meta_150 <- sim_output_14_meta_150 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_150

# Make Summary Table of output
sim_summary_14_meta_150 <- sim_output_14_meta_150 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_14_meta_150

220 Days

#Collect parameters
parms_14_meta_220 <- parms_14_meta
parms_14_meta_220$omega <- 1/220


# Run simulations with the Direct method
set.seed(4)
out_14_meta_220 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_220,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_220 <- out_14_meta_220$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_220 <- ggplot(data = plot_data_14_meta_220, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_220
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_220 <- list()
sim_list_14_meta_220 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_220 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_220 <- out_100_14_meta_220$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_220[[i]] <- sim_data_14_meta_220
}

sim_output_14_meta_220 <- bind_rows(sim_list_14_meta_220)
# Summary table of endpoint data
sim_output_14_meta_220 <- sim_output_14_meta_220 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_220

# Make Summary Table of output
sim_summary_14_meta_220 <- sim_output_14_meta_220 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_14_meta_220

270 Days

#Collect parameters
parms_14_meta_270 <- parms_14_meta
parms_14_meta_270$omega <- 1/270


# Run simulations with the Direct method
set.seed(4)
out_14_meta_270 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_270,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_270 <- out_14_meta_270$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_270 <- ggplot(data = plot_data_14_meta_270, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_270
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_270 <- list()
sim_list_14_meta_270 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_270 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_270 <- out_100_14_meta_270$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_270[[i]] <- sim_data_14_meta_270
}

sim_output_14_meta_270 <- bind_rows(sim_list_14_meta_270)
# Summary table of endpoint data
sim_output_14_meta_270 <- sim_output_14_meta_270 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_270

# Make Summary Table of output
sim_summary_14_meta_270 <- sim_output_14_meta_270 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_14_meta_270

365 Days

#Collect parameters
parms_14_meta_365 <- parms_14_meta
parms_14_meta_365$omega <- 1/365


# Run simulations with the Direct method
set.seed(4)
out_14_meta_365 <- ssa(
  x0 = x0_14_meta,
  a = a_14_meta,
  nu = nu_14_meta,
  parms = parms_14_meta_365,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
)


## Extra Plots
plot_data_14_meta_365 <- out_14_meta_365$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "ID", values_to = "count") %>%
  separate(ID, 
           into = c("state", "patch"), 
           sep = "(?<=[A-Za-z])(?=[0-9])") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

plot_14_meta_365 <- ggplot(data = plot_data_14_meta_365, aes(x=t, y=count, colour=state))+
  geom_line()+
  facet_wrap(~factor(patch, levels = unique(patch)) ,ncol = 3, scales = "free_y")+
  labs(x="Time",
       y="Frequency")+
  theme_bw()
plot_14_meta_365
## Run multiple simulations and saving output
num_sims <- 1000
sim_list_14_meta_365 <- list()
sim_list_14_meta_365 <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  patchPopSize_3 <-     sample(camps.data$camp_total, 14, replace = TRUE)    # Sample different patch sizes for each sim
  x0_14_meta <- unlist(
      lapply(
        seq_len(U),
        function(x){
          c(patchPopSize_3[x] - initial_infected[x], initial_infected[x], 0, 0, patchPopSize_3[x])
          }
        ))

names(x0_14_meta) <- unlist(lapply(seq_len(U), function(x) paste0(c("S","E","I", "R", "N"), x)))

  out_100_14_meta_365 <- ssa(
    x0 = x0_14_meta,
    a = a_14_meta,
    nu = nu_14_meta,
    parms = parms_14_meta_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_14_meta_365 <- out_100_14_meta_365$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "ID", values_to = "count") %>%
    separate(ID, 
             into = c("state", "patch"), 
             sep = "(?<=[A-Za-z])(?=[0-9])") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, patch, I, N, persist)
  
  sim_list_14_meta_365[[i]] <- sim_data_14_meta_365
}

sim_output_14_meta_365 <- bind_rows(sim_list_14_meta_365)
# Summary table of endpoint data
sim_output_14_meta_365 <- sim_output_14_meta_365 %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_14_meta_365

# Make Summary Table of output
sim_summary_14_meta_365 <- sim_output_14_meta_365 %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_14_meta_365

Results

waning_results_14 <- sim_summary_14_meta %>%
  bind_rows(sim_summary_14_meta_10) %>%
  bind_rows(sim_summary_14_meta_20) %>%
  bind_rows(sim_summary_14_meta_30) %>%
  bind_rows(sim_summary_14_meta_40) %>%
  bind_rows(sim_summary_14_meta_50) %>%
  bind_rows(sim_summary_14_meta_60) %>%
  bind_rows(sim_summary_14_meta_70) %>%
  bind_rows(sim_summary_14_meta_80) %>%
  bind_rows(sim_summary_14_meta_90) %>%
  bind_rows(sim_summary_14_meta_180) %>%
  bind_rows(sim_summary_14_meta_110) %>%
  bind_rows(sim_summary_14_meta_120) %>%
  bind_rows(sim_summary_14_meta_130) %>%
  bind_rows(sim_summary_14_meta_150) %>%
  bind_rows(sim_summary_14_meta_220) %>%
  bind_rows(sim_summary_14_meta_270) %>%
  bind_rows(sim_summary_14_meta_365) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model = "meta",
         patches = 14)

write_csv(waning_results_14, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_14.csv")

waning_results_14
ggplot(waning_results_14, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

Combined Results

Results from sinale and metapopulation models were comined into one data frame and visualised.

combined_waning <- waning_results %>%
  bind_rows(waning_results_single) %>%
  bind_rows(waning_results_7) %>%
  bind_rows(waning_results_3) %>%
  bind_rows(waning_results_14)

head(combined_waning)


#write_csv(combined_waning, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/combined_waning_results.csv")
pal <- wes_palette(4, name = "Zissou1", type = "continuous")

combined_plot <- ggplot(combined_waning, aes(immunity_duration, sum_persist, colour = as.factor(patches)))+
  geom_line(alpha=0.7, size=1)+
  geom_point(alpha=0.5, size=2)+
  geom_segment(x = -Inf, y = 50, xend = 141.5, yend = 50, linetype = "dashed", colour = "grey") +
  geom_segment(x = 5, y = 50, xend = 5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 42.5, y = 50, xend = 42.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 91.5, y = 50, xend = 91.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  geom_segment(x = 141.5, y = 50, xend = 141.5, yend = -Inf, linetype = "dashed", colour = "grey") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  scale_x_continuous(breaks = seq(0, 360, 50)) +
  labs(x = "Duration of immunity (days)",
       y = "Probability of persistence after 3 years (%)", 
       colour = "No. Patches")+
  scale_color_discrete(type = pal,
                       labels = c("1", "3", "7", "14"))+
  theme_bw()

combined_plot

ggsave(filename = "combined_plot_patches.pdf", plot = combined_plot, device = "pdf", width = 7, height = 5, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")

ggplot(combined_waning, aes(immunity_duration, mean_percent_infected, colour = as.factor(patches)))+
  geom_line()+
  geom_point() +
  labs(x = "Duration of immunity",
       y = "Proportion infected at endpoint (%)", 
       colour = "Patches")+
  scale_color_discrete(type = pal,
                       labels = c("1", "3", "7", "14"))+
  theme_bw()

3-Patch Single Population

Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
N_a <-    sum(sample(camps.data$camp_total, 3))    # Population size
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

names(x0_a) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Run Single Population Model


EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single
[1] 0.03332608
expexted_infecteds <- EIE_single*N_a # number of expected infecteds at equilibrium
expexted_infecteds
[1] 4.898934
sqrt(N_a) # magnitude of oscillations 
[1] 12.12436
# Run simulations with the Direct method
set.seed(21)
out_a <- ssa(
  x0 = x0_a,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data_a <- out_a$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot_a <- ggplot(data = plot_data_a, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot_a

plot_data_a %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 32 with 31 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_a <- list()
sim_list_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_a <- out_100_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_a[[i]] <- sim_data_a
}

sim_output_a <- bind_rows(sim_list_a)
# Summary table of endpoint data
sim_output_a <- sim_output_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output_a)

# Make Summary Table of output
sim_summary_a <- sim_output_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_a

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0_a <- list()
sim_list_0_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_0_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0_a <- out_100_0_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0_a[[i]] <- sim_data_0_a
}

sim_output_0_a <- bind_rows(sim_list_0_a)
# Summary table of endpoint data
sim_output_0_a <- sim_output_0_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0_a

# Make Summary Table of output
sim_summary_0_a <- sim_output_0_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0_a

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1_a <- list()
sim_list_1_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_1_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1_a <- out_100_1_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1_a[[i]] <- sim_data_1_a
}

sim_output_1_a <- bind_rows(sim_list_1_a)
# Summary table of endpoint data
sim_output_1_a <- sim_output_1_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1_a

# Make Summary Table of output
sim_summary_1_a <- sim_output_1_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1_a

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_a <- list()
sim_list_3_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_3_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_a <- out_100_3_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3_a[[i]] <- sim_data_3_a
}

sim_output_3_a <- bind_rows(sim_list_3_a)
# Summary table of endpoint data
sim_output_3_a <- sim_output_3_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_a

# Make Summary Table of output
sim_summary_3_a <- sim_output_3_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_a

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7_a <- list()
sim_list_7_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))   # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_7_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7_a <- out_100_7_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7_a[[i]] <- sim_data_7_a
}

sim_output_7_a <- bind_rows(sim_list_7_a)
# Summary table of endpoint data
sim_output_7_a <- sim_output_7_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7_a

# Make Summary Table of output
sim_summary_7_a <- sim_output_7_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7_a

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10_a <- list()
sim_list_10_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_10_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10_a <- out_100_10_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10_a[[i]] <- sim_data_10_a
}

sim_output_10_a <- bind_rows(sim_list_10_a)
# Summary table of endpoint data
sim_output_10_a <- sim_output_10_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10_a

# Make Summary Table of output
sim_summary_10_a <- sim_output_10_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10_a

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20_a <- list()
sim_list_20_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_20_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20_a <- out_100_20_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20_a[[i]] <- sim_data_20_a
}

sim_output_20_a <- bind_rows(sim_list_20_a)
# Summary table of endpoint data
sim_output_20_a <- sim_output_20_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20_a

# Make Summary Table of output
sim_summary_20_a <- sim_output_20_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20_a

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30_a <- list()
sim_list_30_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_30_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30_a <- out_100_30_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30_a[[i]] <- sim_data_30_a
}

sim_output_30_a <- bind_rows(sim_list_30_a)
# Summary table of endpoint data
sim_output_30_a <- sim_output_30_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30_a

# Make Summary Table of output
sim_summary_30_a <- sim_output_30_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30_a

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40_a <- list()
sim_list_40_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_40_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40_a <- out_100_40_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40_a[[i]] <- sim_data_40_a
}
View(combined_waning)

sim_output_40_a <- bind_rows(sim_list_40_a)
# Summary table of endpoint data
sim_output_40_a <- sim_output_40_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40_a

# Make Summary Table of output
sim_summary_40_a <- sim_output_40_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40_a

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50_a <- list()
sim_list_50_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_50_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50_a <- out_100_50_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50_a[[i]] <- sim_data_50_a
}

sim_output_50_a <- bind_rows(sim_list_50_a)
# Summary table of endpoint data
sim_output_50_a <- sim_output_50_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50_a

# Make Summary Table of output
sim_summary_50_a <- sim_output_50_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50_a

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60_a <- list()
sim_list_60_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_60_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60_a <- out_100_60_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60_a[[i]] <- sim_data_60_a
}

sim_output_60_a <- bind_rows(sim_list_60_a)
# Summary table of endpoint data
sim_output_60_a <- sim_output_60_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60_a

# Make Summary Table of output
sim_summary_60_a <- sim_output_60_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60_a

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70_a <- list()
sim_list_70_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_70_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70_a <- out_100_70_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70_a[[i]] <- sim_data_70_a
}

sim_output_70_a <- bind_rows(sim_list_70_a)
# Summary table of endpoint data
sim_output_70_a <- sim_output_70_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70_a

# Make Summary Table of output
sim_summary_70_a <- sim_output_70_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70_a

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80_a <- list()
sim_list_80_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_80_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80_a <- out_100_80_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80_a[[i]] <- sim_data_80_a
}

sim_output_80_a <- bind_rows(sim_list_80_a)
# Summary table of endpoint data
sim_output_80_a <- sim_output_80_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80_a

# Make Summary Table of output
sim_summary_80_a <- sim_output_80_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80_a

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150_a <- list()
sim_list_150_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_150_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150_a <- out_100_150_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150_a[[i]] <- sim_data_150_a
}

sim_output_150_a <- bind_rows(sim_list_150_a)
# Summary table of endpoint data
sim_output_150_a <- sim_output_150_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150_a

# Make Summary Table of output
sim_summary_150_a <- sim_output_150_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150_a

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180_a <- list()
sim_list_180_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_180_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180_a <- out_100_180_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180_a[[i]] <- sim_data_180_a
}

sim_output_180_a <- bind_rows(sim_list_180_a)
# Summary table of endpoint data
sim_output_180_a <- sim_output_180_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180_a

# Make Summary Table of output
sim_summary_180_a <- sim_output_180_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180_a

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365_a <- list()
sim_list_365_a <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_a <-     sum(sample(camps.data$camp_total, 3))    # Sample different patch sizes for each sim
  
  x0_a <- c(N_a - initial_infected, initial_infected, 0, 0, N_a)

  names(x0_a) <- c("S","E","I", "R", "N")


  out_100_365_a <- ssa(
    x0 = x0_a,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365_a <- out_100_365_a$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365_a[[i]] <- sim_data_365_a
}

sim_output_365_a <- bind_rows(sim_list_365_a)
# Summary table of endpoint data
sim_output_365_a <- sim_output_365_a %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365_a

# Make Summary Table of output
sim_summary_365_a <- sim_output_365_a %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365_a

Results

waning_results_single_a <- sim_summary_a %>%
  bind_rows(sim_summary_1_a) %>%
  bind_rows(sim_summary_3_a) %>%
  bind_rows(sim_summary_7_a) %>%
  bind_rows(sim_summary_10_a) %>%
  bind_rows(sim_summary_20_a) %>%
  bind_rows(sim_summary_30_a) %>%
  bind_rows(sim_summary_40_a) %>%
  bind_rows(sim_summary_50_a) %>%
  bind_rows(sim_summary_60_a) %>%
  bind_rows(sim_summary_70_a) %>%
  bind_rows(sim_summary_80_a) %>%
  bind_rows(sim_summary_150_a) %>%
  bind_rows(sim_summary_180_a) %>%
  bind_rows(sim_summary_365_a) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 3)

write_csv(waning_results_single_a, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single_a.csv")

waning_results_single_a
NA
ggplot(waning_results_single_a, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

7-Patch Single Population

Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
N_b <-    sum(sample(camps.data$camp_total, 7))    # Population size
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

names(x0_b) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Run Single Population Model


EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single
[1] 0.03332608
expexted_infecteds <- EIE_single*N_b # number of expected infecteds at equilibrium
expexted_infecteds
[1] 6.831846
sqrt(N_b) # magnitude of oscillations 
[1] 14.31782
# Run simulations with the Direct method
set.seed(21)
out_b <- ssa(
  x0 = x0_b,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data_b <- out_b$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot_b <- ggplot(data = plot_data_b, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot_b

plot_data_b %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 32 with 31 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_b <- list()
sim_list_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_b <- out_100_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_b[[i]] <- sim_data_b
}

sim_output_b <- bind_rows(sim_list_b)
# Summary table of endpoint data
sim_output_b <- sim_output_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output_b)

# Make Summary Table of output
sim_summary_b <- sim_output_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_b

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0_b <- list()
sim_list_0_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_0_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0_b <- out_100_0_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0_b[[i]] <- sim_data_0_b
}

sim_output_0_b <- bind_rows(sim_list_0_b)
# Summary table of endpoint data
sim_output_0_b <- sim_output_0_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0_b

# Make Summary Table of output
sim_summary_0_b <- sim_output_0_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0_b

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1_b <- list()
sim_list_1_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_1_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1_b <- out_100_1_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1_b[[i]] <- sim_data_1_b
}

sim_output_1_b <- bind_rows(sim_list_1_b)
# Summary table of endpoint data
sim_output_1_b <- sim_output_1_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1_b

# Make Summary Table of output
sim_summary_1_b <- sim_output_1_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1_b

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_b <- list()
sim_list_3_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_3_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_b <- out_100_3_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3_b[[i]] <- sim_data_3_b
}

sim_output_3_b <- bind_rows(sim_list_3_b)
# Summary table of endpoint data
sim_output_3_b <- sim_output_3_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_b

# Make Summary Table of output
sim_summary_3_b <- sim_output_3_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_b

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7_b <- list()
sim_list_7_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))   # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_7_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7_b <- out_100_7_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7_b[[i]] <- sim_data_7_b
}

sim_output_7_b <- bind_rows(sim_list_7_b)
# Summary table of endpoint data
sim_output_7_b <- sim_output_7_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7_b

# Make Summary Table of output
sim_summary_7_b <- sim_output_7_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7_b

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10_b <- list()
sim_list_10_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_10_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10_b <- out_100_10_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10_b[[i]] <- sim_data_10_b
}

sim_output_10_b <- bind_rows(sim_list_10_b)
# Summary table of endpoint data
sim_output_10_b <- sim_output_10_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10_b

# Make Summary Table of output
sim_summary_10_b <- sim_output_10_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10_b

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20_b <- list()
sim_list_20_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_20_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20_b <- out_100_20_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20_b[[i]] <- sim_data_20_b
}

sim_output_20_b <- bind_rows(sim_list_20_b)
# Summary table of endpoint data
sim_output_20_b <- sim_output_20_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20_b

# Make Summary Table of output
sim_summary_20_b <- sim_output_20_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20_b

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30_b <- list()
sim_list_30_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_30_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30_b <- out_100_30_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30_b[[i]] <- sim_data_30_b
}

sim_output_30_b <- bind_rows(sim_list_30_b)
# Summary table of endpoint data
sim_output_30_b <- sim_output_30_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30_b

# Make Summary Table of output
sim_summary_30_b <- sim_output_30_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30_b

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40_b <- list()
sim_list_40_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_40_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40_b <- out_100_40_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40_b[[i]] <- sim_data_40_b
}

sim_output_40_b <- bind_rows(sim_list_40_b)
# Summary table of endpoint data
sim_output_40_b <- sim_output_40_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40_b

# Make Summary Table of output
sim_summary_40_b <- sim_output_40_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40_b

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50_b <- list()
sim_list_50_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_50_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50_b <- out_100_50_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50_b[[i]] <- sim_data_50_b
}

sim_output_50_b <- bind_rows(sim_list_50_b)
# Summary table of endpoint data
sim_output_50_b <- sim_output_50_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50_b

# Make Summary Table of output
sim_summary_50_b <- sim_output_50_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50_b

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60_b <- list()
sim_list_60_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_60_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60_b <- out_100_60_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60_b[[i]] <- sim_data_60_b
}

sim_output_60_b <- bind_rows(sim_list_60_b)
# Summary table of endpoint data
sim_output_60_b <- sim_output_60_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60_b

# Make Summary Table of output
sim_summary_60_b <- sim_output_60_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60_b

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70_b <- list()
sim_list_70_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_70_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70_b <- out_100_70_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70_b[[i]] <- sim_data_70_b
}

sim_output_70_b <- bind_rows(sim_list_70_b)
# Summary table of endpoint data
sim_output_70_b <- sim_output_70_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70_b

# Make Summary Table of output
sim_summary_70_b <- sim_output_70_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70_b

80 Days

# Summary table of endpoint data
sim_output_80_b <- sim_output_80_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80_b

# Make Summary Table of output
sim_summary_80_b <- sim_output_80_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80_b

90 Days

#Collect parameters
parms_90 <- parms
parms_90$omega <- 1/90


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_90_b <- list()
sim_list_90_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_90_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_90_b <- out_100_90_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_90_b[[i]] <- sim_data_90_b
}

sim_output_90_b <- bind_rows(sim_list_90_b)
# Summary table of endpoint data
sim_output_90_b <- sim_output_90_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_90_b

# Make Summary Table of output
sim_summary_90_b <- sim_output_90_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_90_b

110 Days

#Collect parameters
parms_110 <- parms
parms_110$omega <- 1/110


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_110_b <- list()
sim_list_110_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_110_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_110_b <- out_100_110_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_110_b[[i]] <- sim_data_110_b
}

sim_output_110_b <- bind_rows(sim_list_110_b)
# Summary table of endpoint data
sim_output_110_b <- sim_output_110_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_110_b

# Make Summary Table of output
sim_summary_110_b <- sim_output_110_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_110_b

120 Days

#Collect parameters
parms_120 <- parms
parms_120$omega <- 1/120


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_120_b <- list()
sim_list_120_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_120_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_120_b <- out_100_120_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_120_b[[i]] <- sim_data_120_b
}

sim_output_120_b <- bind_rows(sim_list_120_b)
# Summary table of endpoint data
sim_output_120_b <- sim_output_120_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_120_b

# Make Summary Table of output
sim_summary_120_b <- sim_output_120_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_120_b

130 Days

#Collect parameters
parms_130 <- parms
parms_130$omega <- 1/130


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_130_b <- list()
sim_list_130_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_130_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_130_b <- out_100_130_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_130_b[[i]] <- sim_data_130_b
}

sim_output_130_b <- bind_rows(sim_list_130_b)
# Summary table of endpoint data
sim_output_130_b <- sim_output_130_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_130_b

# Make Summary Table of output
sim_summary_130_b <- sim_output_130_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_130_b

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150_b <- list()
sim_list_150_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_150_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150_b <- out_100_150_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150_b[[i]] <- sim_data_150_b
}

sim_output_150_b <- bind_rows(sim_list_150_b)
# Summary table of endpoint data
sim_output_150_b <- sim_output_150_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150_b

# Make Summary Table of output
sim_summary_150_b <- sim_output_150_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150_b

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180_b <- list()
sim_list_180_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_180_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180_b <- out_100_180_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180_b[[i]] <- sim_data_180_b
}

sim_output_180_b <- bind_rows(sim_list_180_b)
# Summary table of endpoint data
sim_output_180_b <- sim_output_180_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180_b

# Make Summary Table of output
sim_summary_180_b <- sim_output_180_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180_b

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365_b <- list()
sim_list_365_b <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_b <-     sum(sample(camps.data$camp_total, 7))    # Sample different patch sizes for each sim
  
  x0_b <- c(N_b - initial_infected, initial_infected, 0, 0, N_b)

  names(x0_b) <- c("S","E","I", "R", "N")


  out_100_365_b <- ssa(
    x0 = x0_b,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365_b <- out_100_365_b$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365_b[[i]] <- sim_data_365_b
}

sim_output_365_b <- bind_rows(sim_list_365_b)
# Summary table of endpoint data
sim_output_365_b <- sim_output_365_b %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365_b

# Make Summary Table of output
sim_summary_365_b <- sim_output_365_b %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365_b

Results

waning_results_single_b <- sim_summary_b %>%
  bind_rows(sim_summary_1_b) %>%
  bind_rows(sim_summary_3_b) %>%
  bind_rows(sim_summary_7_b) %>%
  bind_rows(sim_summary_10_b) %>%
  bind_rows(sim_summary_20_b) %>%
  bind_rows(sim_summary_30_b) %>%
  bind_rows(sim_summary_40_b) %>%
  bind_rows(sim_summary_50_b) %>%
  bind_rows(sim_summary_60_b) %>%
  bind_rows(sim_summary_70_b) %>%
  bind_rows(sim_summary_80_b) %>%
  bind_rows(sim_summary_90_b) %>%
  bind_rows(sim_summary_110_b) %>%
  bind_rows(sim_summary_120_b) %>%
  bind_rows(sim_summary_130_b) %>%
  bind_rows(sim_summary_150_b) %>%
  bind_rows(sim_summary_180_b) %>%
  bind_rows(sim_summary_365_b) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 7)

write_csv(waning_results_single_b, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single_b.csv")

waning_results_single_b
NA
ggplot(waning_results_single_b, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

14-Patch Single Population

Model Set-up

Model was set up with a single randomly selected camp size with a single infected individual and parameters for pathogen X.

# Define Paramenters
N_c <-    sum(sample(camps.data$camp_total, 14))    # Population size
initial_infected <-  1    # Initial infected
simName <- "SEIRS model"       # Simulation name
tf <- 365*3

#Collect parameters
parms <- list(
  beta = 0.6,
  sigma = 0.175,                          # E to I rate
  gamma = 0.2,                           # I to R rate
  omega = 1/100,                         # R to S rate
  mu = demo_sum$Birth_rate_daily_Mean,                            # Birth/death rate per person per day
  alpha = 1/1000) 

#Create the named initial state vector for the U-patch system.

x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

names(x0_c) <- c("S","E","I", "R", "N")


# Define the state change matrix for a single patch
nu <- matrix(c( -1,  0,  0, +1, +1, -1,  0,  0,  0,  0, # S
                +1, -1,  0,  0,  0,  0, -1,  0,  0,  0, # E
                0, +1, -1,  0,  0,  0,  0, -1,  0, -1, # I
                0,  0, +1, -1,  0,  0,  0,  0, -1,  0, # R 
                0,  0,  0,  0, +1, -1 ,-1, -1, -1, -1), # N
             nrow=5,byrow=TRUE)

# Define propensity functions
a <-c(
        paste0("(beta*I/N)*S"), # Infection
        paste0("sigma*E"),                                       # Becomes infecious
        paste0("gamma*I"),                                       # Recovery from infection
        paste0("omega*R"),       # Loss of immunity
        paste0("mu*N"),                             # Births
        paste0("mu*S"),                                             # Deaths (S)
        paste0("mu*E"),                                             # Deaths (E)
        paste0("mu*I"),                                             # Deaths (I)
        paste0("mu*R"),                                             # Deaths (R)
        paste0("alpha*I")                                           # Deaths from infection
        
      )

Run Single Population Model


EIE_single <- EIE(R0_single, parms) # proportion of expected infecteds at equilibrium
EIE_single
[1] 0.03332608
expexted_infecteds <- EIE_single*N_c # number of expected infecteds at equilibrium
expexted_infecteds
[1] 19.59573
sqrt(N_c) # magnitude of oscillations 
[1] 24.24871
# Run simulations with the Direct method
set.seed(21)
out_c <- ssa(
  x0 = x0_c,
  a = a,
  nu = nu,
  parms = parms,
  tf = tf,
  method = ssa.d(),
  simName = simName,
  verbose = FALSE,
  consoleInterval = 1
) 



## Extra Plots
plot_data_c <- out_c$data %>%
  as_tibble() %>%
  pivot_longer(!t, names_to = "state", values_to = "count") %>%
  mutate(state = factor(state, levels = c("S", "E", "I", "R", "N"))) #%>%
  #filter(state != "N")

single_plot_c <- ggplot(data = plot_data_c, aes(x=t, y=count, colour=state))+
  geom_line(alpha=0.8)+
  labs(x="Time (Days)",
       y="Number of Individuals", 
       colour="State")+
  geom_hline(yintercept = expexted_infecteds, linetype = 'dashed') +
  theme_bw()

single_plot_c

plot_data_c %>%
  filter(state == "I") %>%
  slice_max(count)

Outbreak peaked at day 32 with 31 infected individuals.

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_c <- list()
sim_list_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  set.seed(i)
  out_100_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_c <- out_100_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_c[[i]] <- sim_data_c
}

sim_output_c <- bind_rows(sim_list_c)
# Summary table of endpoint data
sim_output_c <- sim_output_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
head(sim_output_c)

# Make Summary Table of output
sim_summary_c <- sim_output_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100, 
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/100)
sim_summary_c

Varying waining immunity

Waning immunity was thought to play an important role in the persistence of pathogen X so we incrementally increased the duration of immunity (by decreasing \(\omega\)) and calculated the probability of persistence after 3 years in 1000 stochastic simulations. Duration of immunity was increased from 1 day to a year.

0 Days

#Collect parameters
parms_0 <- parms
parms_0$omega <- 0

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_0_c <- list()
sim_list_0_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_0_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_0,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_0_c <- out_100_0_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_0_c[[i]] <- sim_data_0_c
}

sim_output_0_c <- bind_rows(sim_list_0_c)
# Summary table of endpoint data
sim_output_0_c <- sim_output_0_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_0_c

# Make Summary Table of output
sim_summary_0_c <- sim_output_0_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 0)
sim_summary_0_c

1 Days

#Collect parameters
parms_1 <- parms
parms_1$omega <- 1

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_1_c <- list()
sim_list_1_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_1_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_1,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_1_c <- out_100_1_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_1_c[[i]] <- sim_data_1_c
}

sim_output_1_c <- bind_rows(sim_list_1_c)
# Summary table of endpoint data
sim_output_1_c <- sim_output_1_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_1_c

# Make Summary Table of output
sim_summary_1_c <- sim_output_1_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1)
sim_summary_1_c

3 Days

#Collect parameters
parms_3 <- parms
parms_3$omega <- 1/3

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_3_c <- list()
sim_list_3_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_3_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_3,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_3_c <- out_100_3_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_3_c[[i]] <- sim_data_3_c
}
# Summary table of endpoint data
sim_output_3_c <- sim_output_3_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_3_c

# Make Summary Table of output
sim_summary_3_c <- sim_output_3_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/3)
sim_summary_3_c

7 Days

#Collect parameters
parms_7 <- parms
parms_7$omega <- 1/7

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_7_c <- list()
sim_list_7_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))   # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_7_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_7,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_7_c <- out_100_7_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_7_c[[i]] <- sim_data_7_c
}

sim_output_7_c <- bind_rows(sim_list_7_c)
# Summary table of endpoint data
sim_output_7_c <- sim_output_7_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_7_c

# Make Summary Table of output
sim_summary_7_c <- sim_output_7_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/7)
sim_summary_7_c

10 Days

#Collect parameters
parms_10 <- parms
parms_10$omega <- 1/10


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_10_c <- list()
sim_list_10_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_10_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_10,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_10_c <- out_100_10_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_10_c[[i]] <- sim_data_10_c
}

sim_output_10_c <- bind_rows(sim_list_10_c)
# Summary table of endpoint data
sim_output_10_c <- sim_output_10_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_10_c

# Make Summary Table of output
sim_summary_10_c <- sim_output_10_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/10)
sim_summary_10_c

20 Days

#Collect parameters
parms_20 <- parms
parms_20$omega <- 1/20

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_20_c <- list()
sim_list_20_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_20_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_20,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_20_c <- out_100_20_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_20_c[[i]] <- sim_data_20_c
}

sim_output_20_c <- bind_rows(sim_list_20_c)
# Summary table of endpoint data
sim_output_20_c <- sim_output_20_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_20_c

# Make Summary Table of output
sim_summary_20_c <- sim_output_20_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/20)
sim_summary_20_c

30 Days

#Collect parameters
parms_30 <- parms
parms_30$omega <- 1/30

## Run multiple simulations and saving output
num_sims <- 1000
sim_list_30_c <- list()
sim_list_30_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_30_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_30,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_30_c <- out_100_30_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_30_c[[i]] <- sim_data_30_c
}

sim_output_30_c <- bind_rows(sim_list_30_c)
# Summary table of endpoint data
sim_output_30_c <- sim_output_30_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_30_c

# Make Summary Table of output
sim_summary_30_c <- sim_output_30_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/30)
sim_summary_30_c

40 Days

#Collect parameters
parms_40 <- parms
parms_40$omega <- 1/40


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_40_c <- list()
sim_list_40_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_40_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_40,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_40_c <- out_100_40_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_40_c[[i]] <- sim_data_40_c
}

sim_output_40_c <- bind_rows(sim_list_40_c)
# Summary table of endpoint data
sim_output_40_c <- sim_output_40_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_40_c

# Make Summary Table of output
sim_summary_40_c <- sim_output_40_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/40)
sim_summary_40_c

50 Days

#Collect parameters
parms_50 <- parms
parms_50$omega <- 1/50


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_50_c <- list()
sim_list_50_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_50_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_50,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_50_c <- out_100_50_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_50_c[[i]] <- sim_data_50_c
}

sim_output_50_c <- bind_rows(sim_list_50_c)
# Summary table of endpoint data
sim_output_50_c <- sim_output_50_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_50_c

# Make Summary Table of output
sim_summary_50_c <- sim_output_50_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/50)
sim_summary_50_c

60 Days

#Collect parameters
parms_60 <- parms
parms_60$omega <- 1/60


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_60_c <- list()
sim_list_60_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_60_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_60,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_60_c <- out_100_60_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_60_c[[i]] <- sim_data_60_c
}

sim_output_60_c <- bind_rows(sim_list_60_c)
# Summary table of endpoint data
sim_output_60_c <- sim_output_60_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_60_c

# Make Summary Table of output
sim_summary_60_c <- sim_output_60_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/60)
sim_summary_60_c

70 Days

#Collect parameters
parms_70 <- parms
parms_70$omega <- 1/70


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_70_c <- list()
sim_list_70_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_70_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_70,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_70_c <- out_100_70_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_70_c[[i]] <- sim_data_70_c
}

sim_output_70_c <- bind_rows(sim_list_70_c)
# Summary table of endpoint data
sim_output_70_c <- sim_output_70_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_70_c

# Make Summary Table of output
sim_summary_70_c <- sim_output_70_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist)/num_sims)*100,
            mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/70)
sim_summary_70_c

80 Days

#Collect parameters
parms_80 <- parms
parms_80$omega <- 1/80


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_80_c <- list()
sim_list_80_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_80_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_80,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_80_c <- out_100_80_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_80_c[[i]] <- sim_data_80_c
}

sim_output_80_c <- bind_rows(sim_list_80_c)
# Summary table of endpoint data
sim_output_80_c <- sim_output_80_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_80_c

# Make Summary Table of output
sim_summary_80_c <- sim_output_80_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/80)
sim_summary_80_c

90 Days

#Collect parameters
parms_90 <- parms
parms_90$omega <- 1/90


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_90_c <- list()
sim_list_90_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_90_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_90,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_90_c <- out_100_90_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_90_c[[i]] <- sim_data_90_c
}
# Summary table of endpoint data
sim_output_90_c <- sim_output_90_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_90_c

# Make Summary Table of output
sim_summary_90_c <- sim_output_90_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/90)
sim_summary_90_c

110 Days

#Collect parameters
parms_110 <- parms
parms_110$omega <- 1/110


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_110_c <- list()
sim_list_110_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_110_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_110,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_110_c <- out_100_110_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_110_c[[i]] <- sim_data_110_c
}

sim_output_110_c <- bind_rows(sim_list_110_c)
# Summary table of endpoint data
sim_output_110_c <- sim_output_110_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_110_c

# Make Summary Table of output
sim_summary_110_c <- sim_output_110_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/110)
sim_summary_110_c

120 Days

#Collect parameters
parms_120 <- parms
parms_120$omega <- 1/120


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_120_c <- list()
sim_list_120_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_120_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_120,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_120_c <- out_100_120_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_120_c[[i]] <- sim_data_120_c
}
# Summary table of endpoint data
sim_output_120_c <- sim_output_120_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_120_c

# Make Summary Table of output
sim_summary_120_c <- sim_output_120_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/120)
sim_summary_120_c

130 Days

#Collect parameters
parms_130 <- parms
parms_130$omega <- 1/130


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_130_c <- list()
sim_list_130_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_130_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_130,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_130_c <- out_100_130_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_130_c[[i]] <- sim_data_130_c
}
# Summary table of endpoint data
sim_output_130_c <- sim_output_130_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_130_c

# Make Summary Table of output
sim_summary_130_c <- sim_output_130_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/130)
sim_summary_130_c

150 Days

#Collect parameters
parms_150 <- parms
parms_150$omega <- 1/150


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_150_c <- list()
sim_list_150_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_150_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_150,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_150_c <- out_100_150_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_150_c[[i]] <- sim_data_150_c
}

sim_output_150_c <- bind_rows(sim_list_150_c)
# Summary table of endpoint data
sim_output_150_c <- sim_output_150_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_150_c

# Make Summary Table of output
sim_summary_150_c <- sim_output_150_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/150)
sim_summary_150_c

180 Days

#Collect parameters
parms_180 <- parms
parms_180$omega <- 1/180


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_180_c <- list()
sim_list_180_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_180_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_180,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_180_c <- out_100_180_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_180_c[[i]] <- sim_data_180_c
}

sim_output_180_c <- bind_rows(sim_list_180_c)
# Summary table of endpoint data
sim_output_180_c <- sim_output_180_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_180_c

# Make Summary Table of output
sim_summary_180_c <- sim_output_180_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/180)
sim_summary_180_c

220 Days

#Collect parameters
parms_220 <- parms
parms_220$omega <- 1/220


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_220_c <- list()
sim_list_220_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_220_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_220,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_220_c <- out_100_220_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_220_c[[i]] <- sim_data_220_c
}

sim_output_220_c <- bind_rows(sim_list_220_c)
# Summary table of endpoint data
sim_output_220_c <- sim_output_220_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_220_c

# Make Summary Table of output
sim_summary_220_c <- sim_output_220_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/220)
sim_summary_220_c

270 Days

#Collect parameters
parms_270 <- parms
parms_270$omega <- 1/270


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_270_c <- list()
sim_list_270_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_270_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_270,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_270_c <- out_100_270_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_270_c[[i]] <- sim_data_270_c
}

sim_output_270_c <- bind_rows(sim_list_270_c)
# Summary table of endpoint data
sim_output_270_c <- sim_output_270_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_270_c

# Make Summary Table of output
sim_summary_270_c <- sim_output_270_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/270)
sim_summary_270_c

365 Days

#Collect parameters
parms_365 <- parms
parms_365$omega <- 1/365


## Run multiple simulations and saving output
num_sims <- 1000
sim_list_365_c <- list()
sim_list_365_c <- vector("list", length = num_sims)

for (i in 1:num_sims){
  set.seed(i)
  
  N_c <-     sum(sample(camps.data$camp_total, 14))    # Sample different patch sizes for each sim
  
  x0_c <- c(N_c - initial_infected, initial_infected, 0, 0, N_c)

  names(x0_c) <- c("S","E","I", "R", "N")


  out_100_365_c <- ssa(
    x0 = x0_c,
    a = a,
    nu = nu,
    parms = parms_365,
    tf = tf,
    method = ssa.d(),
    simName = simName,
    verbose = FALSE,
    consoleInterval = 1
  )

  
# Extract Final time point from output data
  sim_data_365_c <- out_100_365_c$data %>%
    as_tibble() %>%
    slice_max(t) %>%
    distinct() %>%
    pivot_longer(!t, names_to = "state", values_to = "count") %>%
    pivot_wider(names_from = state, values_from = count) %>%
    mutate(persist = case_when(I > 0 ~ T, 
                               I == 0 ~ F),
           sim = i) %>%
    select(sim, I, N, persist)
  
  sim_list_365_c[[i]] <- sim_data_365_c
}

sim_output_365_c <- bind_rows(sim_list_365_c)
# Summary table of endpoint data
sim_output_365_c <- sim_output_365_c %>%
  group_by(sim) %>%
  summarise(total_I = sum(I), 
            total_N = sum(N)) %>%
  mutate(percent_persist = total_I/(total_N)*100,
         persist = case_when(total_I > 0 ~ T, 
                               total_I == 0 ~ F))
sim_output_365_c

# Make Summary Table of output
sim_summary_365_c <- sim_output_365_c %>%
  summarise(mean_infecteds = mean(total_I),
            sum_persist = (sum(persist, na.rm = T)/num_sims)*100,              mean_percent_infected = mean(percent_persist)) %>%
  mutate(omega = 1/365)
sim_summary_365_c

Results

waning_results_single_c <- sim_summary_c %>%
  bind_rows(sim_summary_1_c) %>%
  bind_rows(sim_summary_3_c) %>%
  bind_rows(sim_summary_7_c) %>%
  bind_rows(sim_summary_10_c) %>%
  bind_rows(sim_summary_20_c) %>%
  bind_rows(sim_summary_30_c) %>%
  bind_rows(sim_summary_40_c) %>%
  bind_rows(sim_summary_50_c) %>%
  bind_rows(sim_summary_60_c) %>%
  bind_rows(sim_summary_70_c) %>%
  bind_rows(sim_summary_80_c) %>%
  bind_rows(sim_summary_90_c) %>%
  bind_rows(sim_summary_110_c) %>%
  bind_rows(sim_summary_120_c) %>%
  bind_rows(sim_summary_130_c) %>%
  bind_rows(sim_summary_150_c) %>%
  bind_rows(sim_summary_180_c) %>%
  bind_rows(sim_summary_220_c) %>%
  bind_rows(sim_summary_270_c) %>%
  bind_rows(sim_summary_365_c) %>%
  mutate(immunity_duration = 1/omega) %>%
  arrange(immunity_duration) %>%
  mutate(model="single",
         patches = 14)

write_csv(waning_results_single_c, file = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Results/waning_results_single_c.csv")

waning_results_single_c
NA
ggplot(waning_results_single_c, aes(immunity_duration, sum_persist)) +
  geom_line()+
  geom_point()+
  theme_bw()

Combined Meta and Single Results

combined_waning_2 <- read_csv("Results/combined_waning_results.csv")%>%
  bind_rows(waning_results_single_a) %>%
  bind_rows(waning_results_single_b) %>%
  bind_rows(waning_results_single_c)
Rows: 73 Columns: 7── Column specification ─────────────────────────────────────────────────────
Delimiter: ","
chr (1): model
dbl (6): mean_infecteds, sum_persist, mean_percent_infected, omega, immun...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
combined_waning_2
pal <- wes_palette(4, name = "Zissou1", type = "continuous")

combined_plot_2 <- ggplot(combined_waning_2, aes(immunity_duration, sum_persist, colour = as.factor(patches), linetype = model))+
  geom_line(alpha=0.9, size=1)+
  #geom_point(alpha=0.5, size=1.5)+
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  scale_x_continuous(breaks = seq(0, 360, 50)) +
  labs(x = "Duration of immunity (days)",
       y = "Probability of persistence after 3 years (%)", 
       colour = "No. Camps",
       linetype = "Model Type")+
  scale_color_discrete(type = pal,
                         #wes_palettes$AsteroidCity3,
                       labels = c("1", "3", "7", "14"))+
  scale_linetype_discrete(labels = c("Metapopulation", "Single Population")) +
  theme_bw()

combined_plot_2

ggsave(filename = "combined_plot_patches_2.pdf", plot = combined_plot_2, device = "pdf", width = 7, height = 5, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")
pathogenX_bar <- ggplot(pathogenX_results, aes(as.factor(patches), sum_persist, groupName = model, fill = model)) +
  geom_col(position=position_dodge(), colour = "black") +
  scale_y_continuous(breaks = seq(0, 100, 10)) +
  labs(x = "No. Camps",
       y = "Probability of persistence after 3 years (%)",
       fill = "Model Type") +
  scale_fill_discrete(
    type = wes_palettes$AsteroidCity3,
    labels = c("Metapopulation", "Single Population")) +
  theme_bw()

pathogenX_bar

ggsave(filename = "pathogenX_bar.pdf", plot = pathogenX_bar, device = "pdf", width = 7, height = 5, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")

Combined plots

library(ggpubr)
library(grid)
theme_set(theme_pubr())

double_combined_plot <- ggarrange(combined_plot + rremove("xlab") + rremove("ylab"), combined_plot_2 + rremove("xlab") + rremove("ylab"),
          labels = c("A", "B"),
          font.label = list(size = 12, face = "plain"),
          vjust = 1,
          ncol = 2, nrow = 1,
          legend.grob = get_legend(combined_plot_2),
          legend = "right"
          )

double_combined_plot <- annotate_figure(double_combined_plot, left = textGrob("Probability of persistence after 3 years (%)", rot = 90, vjust = 1, gp = gpar(cex = 1)),
                    bottom = textGrob("Duration of immunity (days)", hjust = 0.8, gp = gpar(cex = 1)))

double_combined_plot

ggsave(filename = "double_immunity_plot.pdf", plot = double_combined_plot, device = "pdf", width = 8, height = 4, path = "/Users/matthewhoyle/Github_R_projects/Hunter_Gatherer_models/Plots")

GLM Analysis

Model Selection

model1 <- glm(as.integer(sum_persist) ~ immunity_duration + 
                as.factor(model) + 
                as.factor(patches) + 
                as.factor(model)*immunity_duration + 
                as.factor(patches)*immunity_duration + 
                as.factor(model)*as.factor(patches), 
              family = "poisson", data = combined_waning_2)

summary(model1)

Call:
glm(formula = as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(model) * immunity_duration + 
    as.factor(patches) * immunity_duration + as.factor(model) * 
    as.factor(patches), family = "poisson", data = combined_waning_2)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-4.7379  -2.0351  -0.5087   1.3240   3.4231  

Coefficients: (1 not defined because of singularities)
                                              Estimate Std. Error z value Pr(>|z|)    
(Intercept)                                  4.5600462  0.1063474  42.879  < 2e-16 ***
immunity_duration                           -0.0894389  0.0085845 -10.419  < 2e-16 ***
as.factor(model)single                      -0.2719004  0.0598885  -4.540 5.62e-06 ***
as.factor(patches)3                          0.1982695  0.1181171   1.679   0.0932 .  
as.factor(patches)7                          0.1857937  0.1109120   1.675   0.0939 .  
as.factor(patches)14                         0.2044050  0.0970792   2.106   0.0352 *  
immunity_duration:as.factor(model)single    -0.0004272  0.0006113  -0.699   0.4847    
immunity_duration:as.factor(patches)3        0.0578101  0.0086748   6.664 2.66e-11 ***
immunity_duration:as.factor(patches)7        0.0758265  0.0085886   8.829  < 2e-16 ***
immunity_duration:as.factor(patches)14       0.0818046  0.0085765   9.538  < 2e-16 ***
as.factor(model)single:as.factor(patches)3   0.0084098  0.0838230   0.100   0.9201    
as.factor(model)single:as.factor(patches)7   0.0101070  0.0681269   0.148   0.8821    
as.factor(model)single:as.factor(patches)14         NA         NA      NA       NA    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 4504.68  on 127  degrees of freedom
Residual deviance:  599.51  on 116  degrees of freedom
AIC: 1153.8

Number of Fisher Scoring iterations: 6
model2 <- glm(as.integer(sum_persist) ~ immunity_duration + 
                as.factor(model) + 
                as.factor(patches) +
                as.factor(model)*immunity_duration + 
                as.factor(patches)*immunity_duration, family = "poisson", data = combined_waning_2)

summary(model2)

Call:
glm(formula = as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(model) * immunity_duration + 
    as.factor(patches) * immunity_duration, family = "poisson", 
    data = combined_waning_2)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-4.7424  -2.0326  -0.5108   1.3114   3.4187  

Coefficients:
                                           Estimate Std. Error z value Pr(>|z|)    
(Intercept)                               4.5534696  0.0966516  47.112  < 2e-16 ***
immunity_duration                        -0.0894127  0.0085820 -10.419  < 2e-16 ***
as.factor(model)single                   -0.2653238  0.0402294  -6.595 4.24e-11 ***
as.factor(patches)3                       0.2058864  0.0993817   2.072   0.0383 *  
as.factor(patches)7                       0.1941972  0.0965546   2.011   0.0443 *  
as.factor(patches)14                      0.2071325  0.0952989   2.174   0.0297 *  
immunity_duration:as.factor(model)single -0.0004534  0.0005742  -0.789   0.4298    
immunity_duration:as.factor(patches)3     0.0577866  0.0086701   6.665 2.65e-11 ***
immunity_duration:as.factor(patches)7     0.0758062  0.0085875   8.828  < 2e-16 ***
immunity_duration:as.factor(patches)14    0.0817982  0.0085762   9.538  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 4504.68  on 127  degrees of freedom
Residual deviance:  599.53  on 118  degrees of freedom
AIC: 1149.9

Number of Fisher Scoring iterations: 6
library(lmtest)

lrtest(model1, model2)
Likelihood ratio test

Model 1: as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(model) * immunity_duration + 
    as.factor(patches) * immunity_duration + as.factor(model) * 
    as.factor(patches)
Model 2: as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(model) * immunity_duration + 
    as.factor(patches) * immunity_duration
  #Df  LogLik Df  Chisq Pr(>Chisq)
1  12 -564.92                     
2  10 -564.93 -2 0.0238     0.9882
model3 <- glm(as.integer(sum_persist) ~ immunity_duration + 
                as.factor(model) + 
                as.factor(patches) + 
                as.factor(patches)*immunity_duration, 
              family = "poisson", data = combined_waning_2)

summary(model3)

Call:
glm(formula = as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(patches) * immunity_duration, 
    family = "poisson", data = combined_waning_2)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-4.6287  -2.0320  -0.4761   1.3015   3.4211  

Coefficients:
                                        Estimate Std. Error z value Pr(>|z|)    
(Intercept)                             4.575086   0.092699  49.354  < 2e-16 ***
immunity_duration                      -0.089866   0.008563 -10.495  < 2e-16 ***
as.factor(model)single                 -0.286940   0.029494  -9.729  < 2e-16 ***
as.factor(patches)3                     0.195274   0.098508   1.982   0.0474 *  
as.factor(patches)7                     0.182574   0.095460   1.913   0.0558 .  
as.factor(patches)14                    0.197867   0.094583   2.092   0.0364 *  
immunity_duration:as.factor(patches)3   0.058031   0.008665   6.697 2.12e-11 ***
immunity_duration:as.factor(patches)7   0.076070   0.008581   8.865  < 2e-16 ***
immunity_duration:as.factor(patches)14  0.082034   0.008571   9.571  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 4504.68  on 127  degrees of freedom
Residual deviance:  600.16  on 119  degrees of freedom
AIC: 1148.5

Number of Fisher Scoring iterations: 6
lrtest(model2, model3)
Likelihood ratio test

Model 1: as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(model) * immunity_duration + 
    as.factor(patches) * immunity_duration
Model 2: as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(patches) * immunity_duration
  #Df  LogLik Df  Chisq Pr(>Chisq)
1  10 -564.93                     
2   9 -565.24 -1 0.6239     0.4296
model4 <- glm(as.integer(sum_persist) ~ immunity_duration +
                as.factor(patches) +
                as.factor(patches)*immunity_duration, 
              family = "poisson", data = combined_waning_2)

summary(model4)

Call:
glm(formula = as.integer(sum_persist) ~ immunity_duration + as.factor(patches) + 
    as.factor(patches) * immunity_duration, family = "poisson", 
    data = combined_waning_2)

Deviance Residuals: 
   Min      1Q  Median      3Q     Max  
-5.134  -2.019  -0.494   1.299   4.373  

Coefficients:
                                        Estimate Std. Error z value Pr(>|z|)    
(Intercept)                             4.288146   0.087881  48.795  < 2e-16 ***
immunity_duration                      -0.089866   0.008563 -10.495  < 2e-16 ***
as.factor(patches)3                     0.317325   0.097509   3.254 0.001137 ** 
as.factor(patches)7                     0.316486   0.094282   3.357 0.000788 ***
as.factor(patches)14                    0.307372   0.093674   3.281 0.001033 ** 
immunity_duration:as.factor(patches)3   0.058886   0.008663   6.797 1.06e-11 ***
immunity_duration:as.factor(patches)7   0.076340   0.008581   8.897  < 2e-16 ***
immunity_duration:as.factor(patches)14  0.082396   0.008570   9.614  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 4504.68  on 127  degrees of freedom
Residual deviance:  694.85  on 120  degrees of freedom
AIC: 1241.2

Number of Fisher Scoring iterations: 6
lrtest(model3, model4)
Likelihood ratio test

Model 1: as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(patches) * immunity_duration
Model 2: as.integer(sum_persist) ~ immunity_duration + as.factor(patches) + 
    as.factor(patches) * immunity_duration
  #Df  LogLik Df Chisq Pr(>Chisq)    
1   9 -565.24                        
2   8 -612.58 -1 94.69  < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Final GLM

summary(model3)

Call:
glm(formula = as.integer(sum_persist) ~ immunity_duration + as.factor(model) + 
    as.factor(patches) + as.factor(patches) * immunity_duration, 
    family = "poisson", data = combined_waning_2)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-4.6287  -2.0320  -0.4761   1.3015   3.4211  

Coefficients:
                                        Estimate Std. Error z value Pr(>|z|)    
(Intercept)                             4.575086   0.092699  49.354  < 2e-16 ***
immunity_duration                      -0.089866   0.008563 -10.495  < 2e-16 ***
as.factor(model)single                 -0.286940   0.029494  -9.729  < 2e-16 ***
as.factor(patches)3                     0.195274   0.098508   1.982   0.0474 *  
as.factor(patches)7                     0.182574   0.095460   1.913   0.0558 .  
as.factor(patches)14                    0.197867   0.094583   2.092   0.0364 *  
immunity_duration:as.factor(patches)3   0.058031   0.008665   6.697 2.12e-11 ***
immunity_duration:as.factor(patches)7   0.076070   0.008581   8.865  < 2e-16 ***
immunity_duration:as.factor(patches)14  0.082034   0.008571   9.571  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for poisson family taken to be 1)

    Null deviance: 4504.68  on 127  degrees of freedom
Residual deviance:  600.16  on 119  degrees of freedom
AIC: 1148.5

Number of Fisher Scoring iterations: 6

Significance of Coefficients

model5 <- glm(as.integer(sum_persist) ~ 
                immunity_duration + 
                as.factor(model) + 
                as.factor(patches) + 
                as.factor(patches)*immunity_duration, 
              family = "poisson", data = combined_waning_2)

References

LS0tCnRpdGxlOiAiTW9kZWxsaW5nIHRoZSBwZXJzaXN0ZW5jZSBvZiBpbmZlY3Rpb3VzIGRpc2Vhc2VzIGluIHByZS1hZ3JpY3VsdHVyYWwgSHVudGVyLWdhdGhlcmVycyIKc3VidGl0bGU6ICJGaW5hbCBBbmFseXNpcyBSZXBvcnQiCmF1dGhvcjogIk1hdHRoZXcgSG95bGUiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IHRydWUKICAgICAgc21vb3RoX3Njcm9sbDogZmFsc2UKICAgIHRoZW1lOiB5ZXRpCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzCi0tLQojIyBTZXQtdXAKYGBge3J9CiMgcm0obGlzdCA9IGxzKCkpCmxpYnJhcnkod2VzYW5kZXJzb24pCmxpYnJhcnkoR2lsbGVzcGllU1NBKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgojIyBCYWNrZ3JvdW5kCgpUaGUgdHJhZGl0aW9uYWxseSBoZWxkIGJlbGllZiB0aGF0IG1vc3QgbW9kZXJuIGluZmVjdGlvdXMgZGlzZWFzZXMgZW1lcmdlZCB3aGVuIGh1bWFucyBiZWdhbiBsaXZpbmcgaW4gbGFyZ2VyIGFncmljdWx0dXJhbCBzZXR0bGVtZW50cyBoYXMgYmVlbiBjaGFsbGVuZ2VkIGJ5IHN0dWRpZXMgb2YgbW9kZXJuIGh1bnRlci1nYXRoZXJlcnMuIFRoaXMgc3R1ZHkgd2lsbCBpbnZlc3RpZ2F0ZSB3aGljaCBlbWVyZ2luZyBwYXRob2dlbnMgbWF5IHBlcnNpc3QgaW4gaHVudGVyLWdhdGhlcmVyIGdyb3VwcyBieSBjb25zdHJ1Y3RpbmcgYSBjb21wYXJ0bWVudCBtb2RlbCBvZiBpbmZlY3Rpb3VzIGRpc2Vhc2UgdHJhbnNtaXNzaW9uIHRoYXQgYWNjb3VudHMgZm9yIGRlbW9ncmFwaHkgYW5kIG11bHRpLWJhbmQgc3RydWN0dXJlLiBUaGlzIHN0dWR5IHdpbGwgbG9vayB0byB1bmRlcnN0YW5kIGhvdyB0aGUgY3JpdGljYWwgY29tbXVuaXR5IHNpemUgcmVxdWlyZWQgdG8gc3VzdGFpbiBhbiBvdXRicmVhayBpcyBhZmZlY3RlZCBieSBob3N0IHBvcHVsYXRpb24gZHluYW1pY3MuIFdlIHNob3cgdGhhdCBtZXRhcG9wdWxhdGlvbiBzdHJ1Y3R1cmUgaW5jcmVhc2VzIHRoZSBwcm9iYWJpbGl0eSBvZiBhIHJlc3BpcmF0b3J5IHBhdGhvZ2VuIHdpdGggd2FuaW5nIGltbXVuaXR5IHBlcnNpc3RpbmcgYWZ0ZXIgMyB5ZWFycy4gVGhlIHByb2JhYmlsaXR5IG9mIHBlcnNpc3RlbmNlIGluY3JlYXNlcyB3aXRoIHRoZSBudW1iZXIgb2Ygc3ViLXBvcHVsYXRpb25zIGJ1dCBpcyBsYXJnZWx5IGRldGVybWluZWQgYnkgdGhlIGR1cmF0aW9uIG9mIGltbXVuaXR5LiBVbmRlcnN0YW5kaW5nIHRoZSBvcmlnaW5zIG9mIGluZmVjdGlvdXMgZGlzZWFzZXMgaXMgYW4gaW1wb3J0YW50IGFyZWEgb2YgcmVzZWFyY2ggdGhhdCB3aWxsIGxlYWQgdG8gaW1wcm92ZWQgc3RyYXRlZ2llcyBmb3IgcmVkdWNpbmcgdGhlaXIgZ2xvYmFsIGJ1cmRlbi4KClRoaXMgcmVwb3J0IHdpbGwgY292ZXIgdGhlIGZ1bGwgYW5hbHlzaXMgdW5kZXJ0YWtlbiB0byBnZW5lcmF0ZSB0aGUgcmVzdWx0cyB1c2VkIGluIG15IE1TYyBwcm9qZWN0LiBBIGZ1bGwgZGVzY3JpcHRpb24gb2YgdGhlIHJlc2VhcmNoIHByb2plY3QgYWltcyBhbmQgbWV0aG9kcyBjYW4gYmUgZm91bmQgaW4gdGhlIGZpbmFsIHBhcGVyIGluIHRoZSBbYEh1bnRlcl9HYXRoZXJlcl9tb2RlbHNgXShodHRwczovL2dpdGh1Yi5jb20vbWF0dGhld2hveWxlL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMpIEdpdEh1YiByZXBvc2l0b3J5LiAgU29tZSBjb2RlIHVzZWQgaW4gdGhpcyBwcm9qZWN0IHdhcyBhZGFwdGVkIGZyb20gdGhlIHR1dG9yaWFscyBhdHRhY2hlZCB0byB0aGUgYEdpbGxlc3BpZVNTQWAgcGFja2FnZS4gCgojIyBNb2RlbCBQYXJhbWV0ZXIgZXN0aW1hdGlvbgoKIyMjIEFndGEgSHVudGVyLUdhdGhlcmVyIERlbW9ncmFwaHkKCk1vZGVybi1kYXkgaHVudGVyLWdhdGhlcmVycyBhcmUgb2Z0ZW4gdXNlZCB0byBtYWtlIGluZmVyZW5jZXMgYWJvdXQgcHJlLWFncmljdWx0dXJhbCBodW1hbiBwb3B1bGF0aW9ucy4gVGhpcyBzdHVkeSBtb2RlbGVkIHRoZSBob3N0IHBvcHVsYXRpb24gb24gYSBncm91cCBvZiBpbmRpZ2Vub3VzIGh1bnRlci1nYXRoZXJlcnMgZnJvbSB0aGUgTm9ydGhlcm4gUGhpbGxpcGluZXMga25vd24gYXMgdGhlIEFndGEuIEluZm9ybWF0aW9uIHJlZ2FyZGluZyBiaXJ0aHMsIGRlYXRocyBhbmQgcG9wdWxhdGlvbiBzaXplIHdlcmUgb2J0YWluIGZyb20gYSBzdHVkeSBjb25kdWN0ZWQgYnkgSGVhZGxhbmQgZXQgYWwuLCAoMjAxMSkuIEF1dGhvcnMgY29uZHVjdGVkIGEgY2Vuc3VzLWxpa2Ugc3VydmV5IG9mIHRoZSBBZ3RhIHRoYXQgZm9sbG93ZWQgJFxzaW0kNCwzMDAgaW5kaXZpZHVhbHMgb3ZlciB0aGUgcGVyaW9kIG9mIDE5NTAtMjAxMC4gVGhpcyBkYXRlIHdhcyBmaXJzdCBleHBsb3JlZCB0byB1bmRlcnN0YW5kIEFndGEgZGVtb2dyYXBoeS4KCgpgYGB7cn0KYWd0YV9kZW1vIDwtIHJlYWQuY3N2KCJBZ3RhX0RhdGEvQWd0YVBvcER5bmFtaWNzX0hlYWRsYW5kMjAwNy5jc3YiKQoKZ2dwbG90KGFndGFfZGVtbywgYWVzKHg9WWVhcikpICsKICBnZW9tX2xpbmUoYWVzKHk9UG9wU2l6ZSksIGNvbG91ciA9IHdlc19wYWxldHRlcyREYXJqZWVsaW5nMVsxXSkgKwogIGdlb21fbGluZShhZXMoeT1CaXJ0aHMpLCBjb2xvdXIgPSB3ZXNfcGFsZXR0ZXMkRGFyamVlbGluZzFbMl0pICsKICBnZW9tX2xpbmUoYWVzKHk9RGVhdGhzKSwgY29sb3VyID0gd2VzX3BhbGV0dGVzJERhcmplZWxpbmcxWzNdKSArCiAgdGhlbWVfYncoKQpgYGAKCiMjIyMgUG9wdWxhdGlvbiBTaXplCmBgYHtyfQpoaXN0KGFndGFfZGVtbyRQb3BTaXplKQpzdW1tYXJ5KGFndGFfZGVtbyRQb3BTaXplKQpgYGAKCiMjIyMgQmlydGhzCmBgYHtyfQpoaXN0KGFndGFfZGVtbyRCaXJ0aHMpCnN1bW1hcnkoYWd0YV9kZW1vJEJpcnRocykKYGBgCgojIyMjIERlYXRocwpgYGB7cn0KaGlzdChhZ3RhX2RlbW8kRGVhdGhzKQpzdW1tYXJ5KGFndGFfZGVtbyREZWF0aHMpCmBgYAoKIyMjIyBCaXJ0aC9EZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQoKQmlydGggcmF0ZSB3YXMgZXN0aW1hdGVkIGZyb20gdGhpcyBkYXRhIGJ5IHRha2luZyB0aGUgbWVhbiBvZiB0aGUgYW5udWFsIG51bWJlciBvZiBiaXJ0aHMgZGl2aWRlZCBieSB0d28gdGltZXMgdGhlIGFubnVhbCBudW1iZXIgb2YgZmVtYWxlcy4gVGhpcyB3YXMgdGhlbiBzY2FsZWQgYXBwcm9wcmlhdGVseSB0byBvYnRhaW4gdGhlIGRhaWx5IG1lYW4gYmlydGggcmF0ZSBwZXIgcGVyc29uLiAKCmBgYHtyIHdhcm5pbmc9RkFMU0V9CmFndGFfZGVtbyA8LSBhZ3RhX2RlbW8gJT4lCiAgbXV0YXRlKEJpcnRoX3JhdGUgPSBCaXJ0aHMvKEZlbWFsZSoyKSwKICAgICAgICAgQmlydGhfcmF0ZV9kYWlseSA9ICgxICsgQmlydGhfcmF0ZSkgXiAoMS8zNjUpIC0gMSwKICAgICAgICAgRGVhdGhfcmF0ZSA9IChEZWF0aHMvUG9wU2l6ZSksCiAgICAgICAgIERlYXRoX3JhdGVfZGFpbHkgPSAoMSArIERlYXRoX3JhdGUpIF4gKDEvMzY1KSAtIDEsCiAgICAgICAgIFBvcENoYW5nZSA9IChkaWZmID0gUG9wU2l6ZSAtIGxhZyhQb3BTaXplLCBkZWZhdWx0ID0gZmlyc3QoUG9wU2l6ZSkpKSwKICAgICAgICAgUG9wQ2hhbmdlX3JhdGUgPSBhYnMoUG9wQ2hhbmdlKS9Qb3BTaXplLAogICAgICAgICBQb3BDaGFuZ2VfcmF0ZV9kYWlseSA9ICgxICsgUG9wQ2hhbmdlX3JhdGUpIF4gKDEvMzY1KSAtIDEpCmhlYWQoYWd0YV9kZW1vKQoKCmhpc3QoYWd0YV9kZW1vJEJpcnRoX3JhdGUpCmhpc3QoYWd0YV9kZW1vJERlYXRoX3JhdGUpCgpnZ3Bsb3QoYWd0YV9kZW1vLCBhZXMoeD1ZZWFyKSkgKwogIGdlb21fbGluZShhZXMoeT1CaXJ0aF9yYXRlKSwgY29sb3VyID0gd2VzX3BhbGV0dGVzJERhcmplZWxpbmcxWzJdKSArCiAgZ2VvbV9saW5lKGFlcyh5PURlYXRoX3JhdGUpLCBjb2xvdXIgPSB3ZXNfcGFsZXR0ZXMkRGFyamVlbGluZzFbM10pICsKICB0aGVtZV9idygpCgpkZW1vX3N1bSA8LSBhZ3RhX2RlbW8gJT4lCiAgc2VsZWN0KFBvcFNpemUsIEJpcnRoX3JhdGUsIEJpcnRoX3JhdGVfZGFpbHksIERlYXRoX3JhdGUsIERlYXRoX3JhdGVfZGFpbHksIFBvcENoYW5nZV9yYXRlLCBQb3BDaGFuZ2VfcmF0ZV9kYWlseSkgJT4lCiAgICBzdW1tYXJpc2UoYWNyb3NzKAogICAgLmNvbHMgPSBpcy5udW1lcmljLCAKICAgIC5mbnMgPSBsaXN0KE1lYW4gPSBtZWFuLCBTRCA9IHNkKSwgbmEucm0gPSBUUlVFLCAKICAgIC5uYW1lcyA9ICJ7Y29sfV97Zm59IgogICAgKSkKZGVtb19zdW0gCgpkZW1vX3N1bSA8LSBhcy5saXN0KGRlbW9fc3VtKQpgYGAKCiMjIyBBZ3RhIEJhbmQgU2l6ZQoKRGF0YSByZWdhcmRpbmcgY2FtcCBzaXplIG9mIEFndGEgaHVudGVyLWdhdGhlcmVycyB3YXMgb2J0YWluZWQgZnJvbSBhIHN0dWR5IG9mIDYxNSBpbmRpdmlkdWFscyBmcm9tIDE1IGNhbXBzIGluIGluIHRoZSBtdW5pY2lwYWxpdHkgb2YgUGFsYW5hbiwgdGhlIE5vcnRoZXJuIFBoaWxpcHBpbmVzIHB1Ymxpc2hlZCBieSBEeWJsZSBldCBhbC4gKDIwMjEpLgoKYGBge3J9CiMgSW1wb3J0IENhbXAgZGF0YSBmcm9tIE1hcmsgRHlibGUKY2FtcHMuZGF0YSA8LSByZWFkX2NzdigiQWd0YV9EYXRhL2NhbXBzLmNzdiIpCgpoZWFkKGNhbXBzLmRhdGEpCmBgYAoKCmBgYHtyfQojIEV4cGxvcmUgY2FtcCBzaXplCmhpc3QoY2FtcHMuZGF0YSRjYW1wX3RvdGFsKQoKY2FtcC5zaXplIDwtIGNhbXBzLmRhdGEgJT4lCiAgc3VtbWFyaXNlKG1lYW4gPSBtZWFuKGNhbXBfdG90YWwpLAogICAgICAgICAgICBzZCA9IHNkKGNhbXBfdG90YWwpLAogICAgICAgICAgICBtaW4gPSBtaW4oY2FtcF90b3RhbCksCiAgICAgICAgICAgIG1heCA9IG1heChjYW1wX3RvdGFsKSwKICAgICAgICAgICAgdmFyID0gdmFyKGNhbXBfdG90YWwpKQpjYW1wLnNpemUKYGBgCgojIyMgUGF0aG9nZW4gWAoKRm9yIHRoZSBwdXJwb3NlIG9mIHRoaXMgaW52ZXN0aWdhdGlvbiB3ZSBmb3JtdWxhdGVkIGEgaHlwb3RoZXRpY2FsIHJlc3BpcmF0b3J5IHBhdGhvZ2VuLCByZWZlcnJlZCB0byBhcyBwYXRob2dlbiBYLiBUYWtpbmcgaW50byBhY2NvdW50IHRoZSBiaW9sb2dpY2FsIHRyYWRlLW9mZnMgYmV0d2VlbiBoaWdoIHRyYW5zbWlzc2liaWxpdHkgYW5kIGhpZ2ggcGF0aG9nZW5pY2l0eSwgcGF0aG9nZW4gWCB3YXMgZGVjaWRlZCB0byBiZSBoaWdobHkgaW5mZWN0aW91cyB3aXRoIGEgcmVsYXRpdmVseSBsb3cgY2FzZSBmYXRhbGl0eSByYXRlIG9mIDAuMDA1LiBUcmFuc21pc3Npb24gb2NjdXJyZWQgdmlhIGNsb3NlIGNvbnRhY3Qgd2l0aCBhbiBpbmZlY3RlZCBpbmRpdmlkdWFsLiBJbmZlY3Rpb24gd2FzIGNoYXJhY3RlcmlzZWQgYnkgYSBsYXRlbnQgcGVyaW9kIG9mIDUuNyBkYXlzIGZvbGxvd2VkIGJ5IGFuIGluZmVjdGlvdXMgcGVyaW9kIG9mIDUgZGF5cy4gSW5kaXZpZHVhbHMgd2hvIHJlY292ZXJlZCBmcm9tIGluZmVjdGlvbiB3ZXJlIGltbXVuZSBmb3IgMTAwIGRheXMsIGFmdGVyIHdoaWNoIGltbXVuaXR5IHdhbmVkIGFuZCBpbmRpdmlkdWFscyBiZWNhbWUgc3VzY2VwdGlibGUgdG8gcmUtaW5mZWN0aW9uLiBCYXNlZCBvbiB0aGVzZSBjaGFyYWN0ZXJpc3RpY3MsIHRoZSBwYXJhbWV0ZXJzIGluIHRhYmxlIDEgd2VyZSBhc3N1bWVkIGFuZCBpbnB1dCBpbnRvIHRoZSBmaW5hbCBtb2RlbHMuCgoqKlBhcmFtZXRlcioqIHwgKipSYXRlKiogICAgICAgICAgICAgIHwgKipWYWx1ZSoqCi0tLSAgICAgICAgICAgfCAtLS0gICAgICAgICAgICAgICAgICAgfCAtLS0gIAokXGJldGEkICAgICAgIHwgIFRyYW5zbWlzc2lvbiAgICAgICAgIHwgMC42IAokXHNpZ21hJCAgICAgIHwgIEluZmVjdGlvdXMgICAgICAgICAgIHwgMC4xNzUgCiRcZ2FtbWEkICAgICAgfCAgUmVjb3ZlcnkgICAgICAgICAgICAgfCAwLjIgCiRcYWxwaGEkICAgICAgfCAgRGVhdGggZnJvbSBJbmZlY3Rpb24gfCAwLjAwMQokXG9tZWdhJCAgICAgIHwgIFdhbmluZyBJbW11bml0eSAgICAgIHwgMC4wMQoKCgojIyBTaW5nbGUgUG9wdWxhdGlvbiBNb2RlbAoKVG8gaW52ZXN0aWdhdGUgdGhlIHBlcnNpc3RlbmNlIG9mIGEgaHlwb3RoZXRpY2FsIHJlc3BpcmF0b3J5IHBhdGhvZ2VuIGluIGh1bnRlci1nYXRoZXJlcnMsIHRoaXMgc3R1ZHkgY2hvc2UgdG8gc2ltdWxhdGUgZGlzZWFzZSB0cmFuc21pc3Npb24gdXNpbmcgYSBjb21wYXJ0bWVudCBtb2RlbCBhcHByb2FjaCBhcyBvdXRsaW5lZCBpbiB0aGUgaW50cm9kdWN0aW9uLiBUd28gbW9kZWxzIHdlcmUgY29uc3RydWN0ZWQgdG8gaW52ZXN0aWdhdGUgY29tcGFyZSB0aGUgZWZmZWN0IG9mIG1ldGFwb3B1bGF0aW9uIHN0cnVjdHVyZSBvbiBkaXNlYXNlIHBlcnNpc3RlbmNlLiBUaGlzIGZpcnN0IGRlc2NyaWJlcyB0aGUgdHJhbnNtaXNzaW9uIG9mIGEgcGF0aG9nZW4gd2l0aGluIGEgc2luZ2xlIHBvcHVsYXRpb24gd2l0aCBkZW1vZ3JhcGh5IGFuZCB3YW5pbmcgaW1tdW5pdHkgdG8gcmUtaW5mZWN0aW9uIG92ZXIgdGltZS4KCgpcCjxjZW50ZXI+CgoKIVsqRmlndXJlIDEgLSBGbG93IGRpYWdyYW0gb2YgU0VJUlMgbW9kZWwgb2YgdHJhbnNtaXNzaW9uKl0oUGxvdHMvU0VJUlNfRmxvd19EaWFncmFtLnBuZykKCgo8L2NlbnRlcj4KXApcClwKClxiZWdpbnthbGlnbip9CiAgXGZyYWN7e3tcbWF0aHJte2R9fVN9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XG11IE59X3t7XG1hdGhybXtiaXJ0aH19fX4gLSB+XHVuZGVyYnJhY2Uge1xmcmFje1xiZXRhIFNJfXtOfX1fe3tcbWF0aHJte2luZmVjdGlvbn19fX5+ICsgXHVuZGVyYnJhY2Uge1xvbWVnYSBSfV97e1xtYXRocm17bG9zdH19XCx7XG1hdGhybXtpbW11bml0eX19fSAtIFx1bmRlcmJyYWNlIHtcbXUgU31fe3tcbWF0aHJte2RlYXRofX19IFxcCiAgXGZyYWN7e3tcbWF0aHJte2R9fUV9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XGZyYWN7XGJldGEgU0l9e059fV97e1xtYXRocm17aW5mZWN0aW9ufX19fiAtIH5cdW5kZXJicmFjZSB7XHNpZ21hIEV9X3t7XG1hdGhybXtsYXRlbmN5fX19IC0gXHVuZGVyYnJhY2Uge1xtdSBFfV97e1xtYXRocm17ZGVhdGh9fX0gXFwKICBcZnJhY3t7e1xtYXRocm17ZH19SX19e3t7XG1hdGhybXtkfX10fX0gJiA9IFx1bmRlcmJyYWNlIHtcc2lnbWEgRX1fe3tcbWF0aHJte2xhdGVuY3l9fX0gLSBcdW5kZXJicmFjZSB7XGdhbW1hIEl9X3t7XG1hdGhybXtyZWNvdmVyeX19fSAtIH5cdW5kZXJicmFjZSB7XGxlZnQoIHtcbXUgKyBcYWxwaGEgfSBccmlnaHQpSX1fe3tcbWF0aHJte2RlYXRofX19IFxcCiAgXGZyYWN7e3tcbWF0aHJte2R9fVJ9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XGdhbW1hIEl9X3t7XG1hdGhybXtyZWNvdmVyeX19fSAtIFx1bmRlcmJyYWNlIHtcb21lZ2EgUn1fe3tcbWF0aHJte2xvc3R9fVwge1xtYXRocm17aW1tdW5pdHl9fX0gLSBcdW5kZXJicmFjZSB7XG11IFJ9X3t7XG1hdGhybXtkZWF0aH19fQpcZW5ke2FsaWduKn0KClwKXAoKCldoZXJlIHRyYW5zbWlzc2lvbiBpcyBmcmVxdWVuY3kgZGVwZW5kZW50LCAke1xmcmFje1xiZXRhIFNJfXtOfX0kLCAkXGZyYWN7MX17XHNpZ21hfSQgaXMgdGhlIGR1cmF0aW9uIG9mIHRoZSBsYXRlbnQgcGhhc2UsICRcZnJhY3sxfXtcZ2FtbWF9JCBpcyB0aGUgZHVyYXRpb24gb2YgaW5mZWN0aW9uLCAkXGZyYWN7MX17XG9tZWdhfSQgaXMgdGhlIGR1cmF0aW9uIG9mIGltbXVuaXR5IGFuZCBkZWF0aCBmcm9tIGluZmVjdGlvbiBvY2N1cnMgYXQgdGhlIHJhdGUgJFxhbHBoYSQuIEluZGl2aWR1YWxzIGNhbiBiZSBib3JuIGludG8gUyBhbmQgZGllIG5hdHVyYWxseSBmcm9tIGFueSBjb21wYXJ0bWVudCBhdCBhIHJhdGUgb2YgJFxtdSQuCgoKCiMjIyBNb2RlbCBTZXQtdXAKCk1vZGVsIHdhcyBzZXQgdXAgd2l0aCBhIHNpbmdsZSByYW5kb21seSBzZWxlY3RlZCBjYW1wIHNpemUgd2l0aCBhIHNpbmdsZSBpbmZlY3RlZCBpbmRpdmlkdWFsIGFuZCBwYXJhbWV0ZXJzIGZvciBwYXRob2dlbiBYLiAKCmBgYHtyfQojIERlZmluZSBQYXJhbWVudGVycwpOIDwtICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgUG9wdWxhdGlvbiBzaXplCmluaXRpYWxfaW5mZWN0ZWQgPC0gIDEgICAgIyBJbml0aWFsIGluZmVjdGVkCnNpbU5hbWUgPC0gIlNFSVJTIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMwoKI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtcyA8LSBsaXN0KAogIGJldGEgPSAwLjYsCiAgc2lnbWEgPSAwLjE3NSwgICAgICAgICAgICAgICAgICAgICAgICAgICMgRSB0byBJIHJhdGUKICBnYW1tYSA9IDAuMiwgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEkgdG8gUiByYXRlCiAgb21lZ2EgPSAxLzEwMCwgICAgICAgICAgICAgICAgICAgICAgICAgIyBSIHRvIFMgcmF0ZQogIG11ID0gZGVtb19zdW0kQmlydGhfcmF0ZV9kYWlseV9NZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRoL2RlYXRoIHJhdGUgcGVyIHBlcnNvbiBwZXIgZGF5CiAgYWxwaGEgPSAxLzEwMDApIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgpuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKIyBEZWZpbmUgdGhlIHN0YXRlIGNoYW5nZSBtYXRyaXggZm9yIGEgc2luZ2xlIHBhdGNoCm51IDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICAwLCAgMCwgIyBFCiAgICAgICAgICAgICAgICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsIC0xLCAjIEkKICAgICAgICAgICAgICAgIDAsICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICMgUiAKICAgICAgICAgICAgICAgIDAsICAwLCAgMCwgIDAsICsxLCAtMSAsLTEsIC0xLCAtMSwgLTEpLCAjIE4KICAgICAgICAgICAgIG5yb3c9NSxieXJvdz1UUlVFKQoKIyBEZWZpbmUgcHJvcGVuc2l0eSBmdW5jdGlvbnMKYSA8LWMoCiAgICAgICAgcGFzdGUwKCIoYmV0YSpJL04pKlMiKSwgIyBJbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoInNpZ21hKkUiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJlY29tZXMgaW5mZWNpb3VzCiAgICAgICAgcGFzdGUwKCJnYW1tYSpJIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZWNvdmVyeSBmcm9tIGluZmVjdGlvbgogICAgICAgIHBhc3RlMCgib21lZ2EqUiIpLCAgICAgICAjIExvc3Mgb2YgaW1tdW5pdHkKICAgICAgICBwYXN0ZTAoIm11Kk4iKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGhzCiAgICAgICAgcGFzdGUwKCJtdSpTIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFMpCiAgICAgICAgcGFzdGUwKCJtdSpFIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEUpCiAgICAgICAgcGFzdGUwKCJtdSpJIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEkpCiAgICAgICAgcGFzdGUwKCJtdSpSIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFIpCiAgICAgICAgcGFzdGUwKCJhbHBoYSpJIikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgZnJvbSBpbmZlY3Rpb24KICAgICAgICAKICAgICAgKQoKYGBgCgpEZWZpbmUgZnVuY3Rpb25zIHRvIGNhbGN1bGF0ZSBSMCBhbmQgZXhwZWN0ZWQgbnVtYmVyIG9mIHN1c2NlcHRpYmxlcyBhdCBlcXVpbGlicml1bSwgYW5kIGNyaXRpY2FsIGNvbW11bml0eSBzaXplIChEaWVrbWFubiBldCBhbC4sIDIwMTIpLgoKYGBge3J9CiBSMCA8LSBmdW5jdGlvbihwYXJtcykgewogICAocGFybXMkc2lnbWEvKHBhcm1zJHNpZ21hICsgcGFybXMkbXUpKSAqIChwYXJtcyRiZXRhL3Bhcm1zJGdhbW1hICsgcGFybXMkbXUgKyBwYXJtcyRhbHBoYSkKIH0gCiAgCkVJRSA8LSBmdW5jdGlvbihSMCwgcGFybXMpIHsKICB5ID0gKChSMCAtIDEpICogcGFybXMkb21lZ2EpIC8gKHBhcm1zJGdhbW1hICogUjApCiAgcmV0dXJuKHkpCn0KCkNDUyA8LSBmdW5jdGlvbihpbmZlY3Rpb3VzX3BlcmlvZCwgUjApIHsKICB4ID0gaW5mZWN0aW91c19wZXJpb2QvKDIzKjM2NSkgICAgICAgICAgICMgQXZnIGxpZmUgbGlmZSBleHBleGN0YW5jeSBvZiAyMyAoR3VydmVuIGV0IGFsLiAyMDA3KQogIHkgPSAxLygoeF4yKSooKDEtKDEvUjApKV4yKSkKICByZXR1cm4oeSkKfQpgYGAKCiMjIyBDYWxjdWxhdGUgRXBpZGVtaWMgU3RhdGlzdGljcwpgYGB7cn0KCiMgQ2FsY3VsYXRlIFIwLCBleHBlY3RlZCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IGVxdWlsaWJyaXVtLCBtYWduaXR1ZGUgb2Ygb3NjaWxsYXRpb24gYW5kIENDUwpSMF9zaW5nbGUgPC0gUjAocGFybXMpClIwX3NpbmdsZQoKRUlFX3NpbmdsZSA8LSBFSUUoUjBfc2luZ2xlLCBwYXJtcykgIyBwcm9wb3J0aW9uIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpFSUVfc2luZ2xlCgpleHBleHRlZF9pbmZlY3RlZHMgPC0gRUlFX3NpbmdsZSpOICMgbnVtYmVyIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpleHBleHRlZF9pbmZlY3RlZHMKCnNxcnQoTikgIyBtYWduaXR1ZGUgb2Ygb3NjaWxsYXRpb25zIAoKQ0NTX3NpbmdsZSA8LSBDQ1MoaW5mZWN0aW91c19wZXJpb2QgPSA1LCBSMCA9IFIwX3NpbmdsZSkgIyBBdmVyYWdlIGxpZmUgZXhwZWN0YW5jeSBhcyBwZXIgS2FwbGFuIChjcnVkZSkKQ0NTX3NpbmdsZQpgYGAKIyMjIFBsb3QgQ0NTIGJ5IGluZmVjdGlvdXMgcGVyaW9kIGFuZCBSMApgYGB7cn0KaW5mZWN0aW91c19wZXJpb2RzIDwtIHNlcSg1LCAzNjUsIDEwKQoKUjBfc2VxIDwtIHNlcSgxLjEsNSwwLjIpCgp4ID0gaW5mZWN0aW91c19wZXJpb2RzCgp5ID0gUjBfc2VxCgp6ID0gbG9nMTAob3V0ZXIoeCwgeSwgQ0NTKSkKCnBlcnNwM0QoeCwgeSwgeiwKICAgICAgICB6bGltID0gYygwLDEwKSwKICAgICAgICB4bGltID0gYyg1LCAzNjUpLAogICAgICAgIHlsaW0gPSBjKDEsIDUpLAogICAgICAgIHhsYWIgPSAiSW5mZWN0aW91cyBQZXJpb2QgKGRheXMpIiwKICAgICAgICB5bGFiID0gIkJhc2ljIFJlcHJvZHVjdGl2ZSBudW1iZXIgKFIwKSIsCiAgICAgICAgemxhYiA9ICJsb2cxMChDcml0Y2FsIENvbW11bml0eSBTaXplKSIsCiAgICAgICAgc2hhZGUgPSAgMC4xNSwgdGhldGEgPSAxNDAsIHBoaSA9IDMwLCBleHBhbmQgPSAwLjYsCiAgICAgICAgdGlja3R5cGUgPSAiZGV0YWlsZWQiKQpgYGAKCgoKIyMjIFJ1biBTaW5nbGUgUG9wdWxhdGlvbiBNb2RlbApgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyMSkKb3V0IDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtcywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKSAKCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhIDwtIG91dCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKc2luZ2xlX3Bsb3QgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZShhbHBoYT0wLjgpKwogIGxhYnMoeD0iVGltZSAoRGF5cykiLAogICAgICAgeT0iTnVtYmVyIG9mIEluZGl2aWR1YWxzIiwgCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZXhwZXh0ZWRfaW5mZWN0ZWRzLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArCiAgdGhlbWVfYncoKQoKc2luZ2xlX3Bsb3QKCiNnZ3NhdmUoZmlsZW5hbWUgPSAic2luZ2xlX3Bsb3QucGRmIiwgCiAgICAgICAjcGxvdCA9IHNpbmdsZV9wbG90LAogICAgICAgI2RldmljZSA9ICJwZGYiLAogICAgICAgI3dpZHRoID0gNywgCiAgICAgICAjaGVpZ2h0ID0gMywKICAgICAgICNwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvUGxvdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscyIpCmBgYAoKYGBge3J9CnBsb3RfZGF0YSAlPiUKICBmaWx0ZXIoc3RhdGUgPT0gIkkiKSAlPiUKICBzbGljZV9tYXgoY291bnQpCmBgYApPdXRicmVhayBwZWFrZWQgYXQgZGF5IDI1IHdpdGggMTQgaW5mZWN0ZWQgaW5kaXZpZHVhbHMuCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3QgPC0gbGlzdCgpCnNpbV9saXN0IDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBzZXQuc2VlZChpKQogIG91dF8xMDAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YSA8LSBvdXRfMTAwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdFtbaV1dIDwtIHNpbV9kYXRhCn0KCnNpbV9vdXRwdXQgPC0gYmluZF9yb3dzKHNpbV9saXN0KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0IDwtIHNpbV9vdXRwdXQgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpoZWFkKHNpbV9vdXRwdXQpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnkgPC0gc2ltX291dHB1dCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnkKYGBgCgojIyMgVmFyeWluZyB3YWluaW5nIGltbXVuaXR5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQpXYW5pbmcgaW1tdW5pdHkgd2FzIHRob3VnaHQgdG8gcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiB0aGUgcGVyc2lzdGVuY2Ugb2YgcGF0aG9nZW4gWCBzbyB3ZSBpbmNyZW1lbnRhbGx5IGluY3JlYXNlZCB0aGUgZHVyYXRpb24gb2YgaW1tdW5pdHkgKGJ5IGRlY3JlYXNpbmcgJFxvbWVnYSQpIGFuZCBjYWxjdWxhdGVkIHRoZSBwcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzIGluIDEwMDAgc3RvY2hhc3RpYyBzaW11bGF0aW9ucy4gRHVyYXRpb24gb2YgaW1tdW5pdHkgd2FzIGluY3JlYXNlZCBmcm9tIDEgZGF5IHRvIGEgeWVhci4KCiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzAgPC0gcGFybXMKcGFybXNfMCRvbWVnYSA8LSAwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8wIDwtIG91dF8wJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8wCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMCA8LSBsaXN0KCkKc2ltX2xpc3RfMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzAgPC0gb3V0XzEwMF8wJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8wW1tpXV0gPC0gc2ltX2RhdGFfMAp9CgpzaW1fb3V0cHV0XzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMCA8LSBzaW1fb3V0cHV0XzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8wIDwtIHNpbV9vdXRwdXRfMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV8wCmBgYAoKCgoKIyMjIyAxIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMSA8LSBwYXJtcwpwYXJtc18xJG9tZWdhIDwtIDEKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18xLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzEgPC0gb3V0XzEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzEKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xIDwtIGxpc3QoKQpzaW1fbGlzdF8xIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMSA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMSA8LSBvdXRfMTAwXzEkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzFbW2ldXSA8LSBzaW1fZGF0YV8xCn0KCnNpbV9vdXRwdXRfMSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xIDwtIHNpbV9vdXRwdXRfMSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEgPC0gc2ltX291dHB1dF8xICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5XzEKYGBgCgoKCgoKIyMjIyAzIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMyA8LSBwYXJtcwpwYXJtc18zJG9tZWdhIDwtIDEvMwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzMgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMyA8LSBvdXRfMyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzMsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMwpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzMgPC0gbGlzdCgpCnNpbV9saXN0XzMgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zIDwtIG91dF8xMDBfMyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM1tbaV1dIDwtIHNpbV9kYXRhXzMKfQoKc2ltX291dHB1dF8zIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzMgPC0gc2ltX291dHB1dF8zICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMyA8LSBzaW1fb3V0cHV0XzMgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zKQpzaW1fc3VtbWFyeV8zCmBgYAoKIyMjIyA3IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNyA8LSBwYXJtcwpwYXJtc183JG9tZWdhIDwtIDEvNwoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzcgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzcsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNyA8LSBvdXRfNyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF83IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzcsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfNwpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzcgPC0gbGlzdCgpCnNpbV9saXN0XzcgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF83IDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzcsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83IDwtIG91dF8xMDBfNyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfN1tbaV1dIDwtIHNpbV9kYXRhXzcKfQoKc2ltX291dHB1dF83IDwtIGJpbmRfcm93cyhzaW1fbGlzdF83KQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzcgPC0gc2ltX291dHB1dF83ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF83CgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNyA8LSBzaW1fb3V0cHV0XzcgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83KQpzaW1fc3VtbWFyeV83CmBgYAoKIyMjIyAxMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEwIDwtIHBhcm1zCnBhcm1zXzEwJG9tZWdhIDwtIDEvMTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTAgPC0gb3V0XzEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTAgPC0gbGlzdCgpCnNpbV9saXN0XzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMCA8LSBvdXRfMTAwXzEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMFtbaV1dIDwtIHNpbV9kYXRhXzEwCn0KCnNpbV9vdXRwdXRfMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEwIDwtIHNpbV9vdXRwdXRfMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTAgPC0gc2ltX291dHB1dF8xMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwKQpzaW1fc3VtbWFyeV8xMApgYGAKCiMjIyMgMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18yMCA8LSBwYXJtcwpwYXJtc18yMCRvbWVnYSA8LSAxLzIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMjAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzIwIDwtIG91dF8yMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8yMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8yMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8yMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzIwIDwtIGxpc3QoKQpzaW1fbGlzdF8yMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzIwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMjAgPC0gb3V0XzEwMF8yMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMjBbW2ldXSA8LSBzaW1fZGF0YV8yMAp9CgpzaW1fb3V0cHV0XzIwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8yMCA8LSBzaW1fb3V0cHV0XzIwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzIwIDwtIHNpbV9vdXRwdXRfMjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMCkKc2ltX3N1bW1hcnlfMjAKYGBgCgojIyMjIDMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzAgPC0gcGFybXMKcGFybXNfMzAkb21lZ2EgPC0gMS8zMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzMwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc18zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zMCA8LSBvdXRfMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zMCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzMwIDwtIG91dF8xMDBfMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzMwW1tpXV0gPC0gc2ltX2RhdGFfMzAKfQoKc2ltX291dHB1dF8zMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMzAgPC0gc2ltX291dHB1dF8zMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zMCA8LSBzaW1fb3V0cHV0XzMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzApCnNpbV9zdW1tYXJ5XzMwCmBgYAoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzQwIDwtIHBhcm1zCnBhcm1zXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF80MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfNDAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNDAgPC0gb3V0XzQwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzQwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzQwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzQwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNDAgPC0gbGlzdCgpCnNpbV9saXN0XzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNDAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV80MCA8LSBvdXRfMTAwXzQwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF80MFtbaV1dIDwtIHNpbV9kYXRhXzQwCn0KCnNpbV9vdXRwdXRfNDAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzQwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzQwIDwtIHNpbV9vdXRwdXRfNDAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzQwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNDAgPC0gc2ltX291dHB1dF80MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV80MApgYGAKCiMjIyMgNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc181MCA8LSBwYXJtcwpwYXJtc181MCRvbWVnYSA8LSAxLzUwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfNTAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzUwIDwtIG91dF81MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF81MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV81MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF81MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzUwIDwtIGxpc3QoKQpzaW1fbGlzdF81MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzUwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNTAgPC0gb3V0XzEwMF81MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNTBbW2ldXSA8LSBzaW1fZGF0YV81MAp9CgpzaW1fb3V0cHV0XzUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF81MCA8LSBzaW1fb3V0cHV0XzUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzUwIDwtIHNpbV9vdXRwdXRfNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS81MCkKc2ltX3N1bW1hcnlfNTAKYGBgCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNjAgPC0gcGFybXMKcGFybXNfNjAkb21lZ2EgPC0gMS82MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzYwIDwtIHNzYSgKICB4MCA9IHgwLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtc182MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV82MCA8LSBvdXRfNjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfNjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfNjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF82MCA8LSBsaXN0KCkKc2ltX2xpc3RfNjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF82MCA8LSBzc2EoCiAgICB4MCA9IHgwLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc182MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzYwIDwtIG91dF8xMDBfNjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzYwW1tpXV0gPC0gc2ltX2RhdGFfNjAKfQoKc2ltX291dHB1dF82MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNjAgPC0gc2ltX291dHB1dF82MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV82MCA8LSBzaW1fb3V0cHV0XzYwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNjApCnNpbV9zdW1tYXJ5XzYwCmBgYAoKIyMjIyA3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzcwIDwtIHBhcm1zCnBhcm1zXzcwJG9tZWdhIDwtIDEvNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF83MCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfNzAgPC0gb3V0XzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNzAgPC0gbGlzdCgpCnNpbV9saXN0XzcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNzAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83MCA8LSBvdXRfMTAwXzcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF83MFtbaV1dIDwtIHNpbV9kYXRhXzcwCn0KCnNpbV9vdXRwdXRfNzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzcwIDwtIHNpbV9vdXRwdXRfNzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNzAgPC0gc2ltX291dHB1dF83MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcwKQpzaW1fc3VtbWFyeV83MApgYGAKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc184MCA8LSBwYXJtcwpwYXJtc184MCRvbWVnYSA8LSAxLzgwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfODAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzgwIDwtIG91dF84MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF84MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV84MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF84MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzgwIDwtIGxpc3QoKQpzaW1fbGlzdF84MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE4gPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDEpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MCA8LSBjKE4gLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOKQoKICBuYW1lcyh4MCkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzgwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfODAgPC0gb3V0XzEwMF84MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfODBbW2ldXSA8LSBzaW1fZGF0YV84MAp9CgpzaW1fb3V0cHV0XzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF84MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF84MCA8LSBzaW1fb3V0cHV0XzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF84MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzgwIDwtIHNpbV9vdXRwdXRfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfODAKYGBgCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE1MCA8LSBwYXJtcwpwYXJtc18xNTAkb21lZ2EgPC0gMS8xNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNTAgPC0gc3NhKAogIHgwID0geDAsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zXzE1MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNTAgPC0gb3V0XzE1MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTUwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE1MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE1MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTiA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE4pCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTUwIDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzE1MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE1MCA8LSBvdXRfMTAwXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTUwW1tpXV0gPC0gc2ltX2RhdGFfMTUwCn0KCnNpbV9vdXRwdXRfMTUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTUwIDwtIHNpbV9vdXRwdXRfMTUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNTAgPC0gc2ltX291dHB1dF8xNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5XzE1MApgYGAKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTgwIDwtIHBhcm1zCnBhcm1zXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzEwMCA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMTgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE4MCA8LSBvdXRfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE4MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTgwIDwtIGxpc3QoKQpzaW1fbGlzdF8xODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDAgPC0gYyhOIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTikKCiAgbmFtZXMoeDApIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xODAgPC0gc3NhKAogICAgeDAgPSB4MCwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTgwIDwtIG91dF8xMDBfMTgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xODBbW2ldXSA8LSBzaW1fZGF0YV8xODAKfQoKc2ltX291dHB1dF8xODAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE4MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xODAgPC0gc2ltX291dHB1dF8xODAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE4MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE4MCA8LSBzaW1fb3V0cHV0XzE4MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE4MCkKc2ltX3N1bW1hcnlfMTgwCmBgYAoKCiMjIyMgMzY1IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzY1IDwtIHBhcm1zCnBhcm1zXzM2NSRvbWVnYSA8LSAxLzM2NQoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzM2NSA8LSBzc2EoCiAgeDAgPSB4MCwKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXNfMzY1LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzM2NSA8LSBvdXRfMzY1JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzM2NSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zNjUsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMzY1CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMzY1IDwtIGxpc3QoKQpzaW1fbGlzdF8zNjUgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKIE5fYSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCxOX2EpCgogIG5hbWVzKHgwKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMzY1IDwtIHNzYSgKICAgIHgwID0geDAsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzM2NSA8LSBvdXRfMTAwXzM2NSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzY1W1tpXV0gPC0gc2ltX2RhdGFfMzY1Cn0KCnNpbV9vdXRwdXRfMzY1IDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zNjUpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMzY1IDwtIHNpbV9vdXRwdXRfMzY1ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zNjUKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zNjUgPC0gc2ltX291dHB1dF8zNjUgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzM2NQpgYGAKCgoKIyMjIyBSZXN1bHRzCmBgYHtyfQp3YW5pbmdfcmVzdWx0c19zaW5nbGUgPC0gc2ltX3N1bW1hcnkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzQwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV82MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfODApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xMDApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zNjUpICU+JQogIG11dGF0ZShpbW11bml0eV9kdXJhdGlvbiA9IDEvb21lZ2EpICU+JQogIGFycmFuZ2UoaW1tdW5pdHlfZHVyYXRpb24pICU+JQogIG11dGF0ZShtb2RlbD0ic2luZ2xlIiwKICAgICAgICAgcGF0Y2hlcyA9IDEpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfc2luZ2xlLCBmaWxlID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy9SZXN1bHRzL3dhbmluZ19yZXN1bHRzX3NpbmdsZS5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfc2luZ2xlCgpgYGAKCmBgYHtyfQpnZ3Bsb3Qod2FuaW5nX3Jlc3VsdHNfc2luZ2xlLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0KSkgKwogIGdlb21fbGluZSgpKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9idygpCmBgYAoKCgoKIyMgNy1QYXRjaCBNZXRhcG9wdWxhdGlvbiBNb2RlbCAKClJlY2VudCBzdHVkaWVzIGhhdmUgc3VnZ2VzdGVkIHRoYXQgcHJlLWFncmljdWx0dXJhbCBodW50ZXItZ2F0aGVyZXJzIGRpZCBub3QgbGl2ZSBpbiBzbWFsbCBpc29sYXRlZCBncm91cHMgYnV0IGZyb21lZCBpbnRlcmNvbm5lY3RlZCBtdWx0aS1jYW1wIG5ldHdvcmtzLiBUbyBpbnZlc3RpZ2F0ZSB0aGlzIHdlIGJ1aWx0IGEgc2Vjb25kIHBvcHVsYXRpb24gdGhhdCBhY2NvdW50cyBmb3IgbWV0YXBvcHVsYXRpb24gc3RydWN0dXJlIG9mIGh1bnRlci1nYXRoZXJlcnMuIFRoZSBzZWNvbmQgbW9kZWwgZm9sbG93cyBhbiBhbG1vc3QgaWRlbnRpY2FsIGZvcm1hdCBhcyB0aGUgc2luZ2xlIHBvcHVsYXRpb24gbW9kZWwsIGJ1dCBpbnN0ZWFkIGhhcyBiZWVuIGV4cGFuZGVkIHRvIGFjY29tbW9kYXRlIHRoZSBtZXRhcG9wdWxhdGlvbiBzdHJ1Y3R1cmUgb2YgbXVsdGktYmFuZCBodW50ZXItZ2F0aGVyZXIgZ3JvdXBzOgoKClxiZWdpbnthbGlnbip9ClxmcmFje3t7XG1hdGhybXtkfX1TfX17e3tcbWF0aHJte2R9fXR9fSAmID0gXHVuZGVyYnJhY2Uge1xtdV9pIE5faX1fe3tcbWF0aHJte2JpcnRofX19fiAtIH5cdW5kZXJicmFjZSB7XGJpZ2dsKFxmcmFje1xiZXRhX3tpaX0gSV9pfXtOX2l9ICsgXGZyYWN7XGJldGFfe2ppfSBJX2p9IHtOX2p9ICsgLi4uIFxiaWdncilTX2l9X3t7XG1hdGhybXtpbmZlY3Rpb259fX1+fiArIFx1bmRlcmJyYWNlIHtcb21lZ2FfaSBSX2l9X3t7XG1hdGhybXtsb3N0fX1cLHtcbWF0aHJte2ltbXVuaXR5fX19IC0gXHVuZGVyYnJhY2Uge1xtdV9pIFNfaX1fe3tcbWF0aHJte2RlYXRofX19IFxcClxmcmFje3t7XG1hdGhybXtkfX1FfX17e3tcbWF0aHJte2R9fXR9fSAmID0gXHVuZGVyYnJhY2Uge1xiaWdnbChcZnJhY3tcYmV0YV97aWl9IElfaX17Tl9pfSArIFxmcmFje1xiZXRhX3tqaX0gSV9qfSB7Tl9qfSArIC4uLiBcYmlnZ3IpU19pfV97e1xtYXRocm17aW5mZWN0aW9ufX19fiAtIH5cdW5kZXJicmFjZSB7XHNpZ21hX2kgRV9pfV97e1xtYXRocm17bGF0ZW5jeX19fSAtIFx1bmRlcmJyYWNlIHtcbXVfaSBFX2l9X3t7XG1hdGhybXtkZWF0aH19fSBcXApcZnJhY3t7e1xtYXRocm17ZH19SX19e3t7XG1hdGhybXtkfX10fX0gJiA9IFx1bmRlcmJyYWNlIHtcc2lnbWFfaSBFX2l9X3t7XG1hdGhybXtsYXRlbmN5fX19IC0gXHVuZGVyYnJhY2Uge1xnYW1tYV9pIElfaX1fe3tcbWF0aHJte3JlY292ZXJ5fX19IC0gflx1bmRlcmJyYWNlIHtcbGVmdCgge1xtdV9pICsgXGFscGhhX2kgfSBccmlnaHQpSV9pfV97e1xtYXRocm17ZGVhdGh9fX0gXFwKXGZyYWN7e3tcbWF0aHJte2R9fVJ9fXt7e1xtYXRocm17ZH19dH19ICYgPSBcdW5kZXJicmFjZSB7XGdhbW1hX2kgSV9pfV97e1xtYXRocm17cmVjb3Zlcnl9fX0gLSBcdW5kZXJicmFjZSB7XG9tZWdhX2kgUl9pfV97e1xtYXRocm17bG9zdH19XCB7XG1hdGhybXtpbW11bml0eX19fSAtIFx1bmRlcmJyYWNlIHtcbXVfaSBSX2l9X3t7XG1hdGhybXtkZWF0aH19fQpcZW5ke2FsaWduKn0KClRoZXNlIGNvdXBsZWQgZGlmZmVyZW50aWFsIGVxdWF0aW9ucyBkZXNjcmliZSB0aGUgd2l0aGluLXBhdGNoIFNFSVJTLXR5cGUgZHluYW1pY3Mgb2YgdGhlICRpJHRoIHBhdGNoIHdoZXJlIHRoZSBmb3JjZSBvZiBpbmZlY3Rpb24gaXMgZHJpdmVuIGJ5IGNvbnRhY3Qgb2Ygc3VzY2VwdGlibGVzIHdpdGggaW5mZWN0ZWRzIHdpdGhpbiB0aGUgJGkkdGggcGF0Y2ggYW5kIGluIHRoZSAkaiR0aCBvdGhlciBwYXRjaGVzLiBCb3RoIG1vZGVscyBhc3N1bWUgdGhhdCBjb21wYXJ0bWVudHMgYXJlIHdlbGwtbWl4ZWQgYW5kIHRoYXQgdGhlIHdhaXRpbmcgdGltZXMgYmV0d2VlbiBjb21wYXJ0bWVudHMgYXJlIGV4cG9uZW50aWFsbHkgZGlzdHJpYnV0ZWQuIAoKCgoKIyMjIE1vZGVsIFNldC11cApXZSBmaXJzdCBtb2RlbGVkIHRyYW5zbWlzc2lvbiBpbiBhIG1ldGFwb3B1bGF0aW9uIG9mIDcgY2FtcHMsIGFzIG9ic2VydmVkIGJ5IE1pZ2xpYW5vIGV0IGFsLiAoMjAyMyksIHdpdGggb25lIGluaXRpYWxseSBpbmZlY3RlZCBpbmRpdmlkdWFsIGZyb20gYSByYW5kb21seSBzZWxlY3RlZCBwYXRjaC4gCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBQYXRjaCBzaXplClUgPC0gbGVuZ3RoKHBhdGNoUG9wU2l6ZSkgICAgICAgICAgICAgICAgICAgICMgTnVtYmVyIG9mIHBhdGNoZXMKaW5pdGlhbF9pbmZlY3RlZCA8LSAgYXMudmVjdG9yKHJtdWx0aW5vbSgxLCAxLCByZXAoMC41LCBVKSkpICAgIyBJbml0aWFsIGluZmVjdGVkIChpbml0aWFsIGluZmVjdGVkIHBhdGNoIHJhbmRvbWx5IGdlbmVyYXRlZCkKaW5pdGlhbF9pbmZlY3RlZF9wYXRjaCA8LSB3aGljaChpbml0aWFsX2luZmVjdGVkID4gMCkKc2ltTmFtZSA8LSAiU0lSUyBtZXRhcG9wdWxhdGlvbiBtb2RlbCIgICAgICAgIyBTaW11bGF0aW9uIG5hbWUKdGYgPC0gMzY1KjMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRmluYWwgdGltZQoKIyBBZ3RhIEh1bnRlci1HYXRoZXJlciBjb250YWN0IHJhdGVzCndpdGhpbl9wb3BfY29udGFjdCA9IDEKYmV0d2Vlbl9wb3BfY29udGFjdCA9IDAuNS9VICAgICAjIG5vcm1hbGlzZWQgYnkgbnVtYmVyIG9mIHBhdGNoZXMgCgojQ3JlYXRlIHRoZSBuYW1lZCBpbml0aWFsIHN0YXRlIHZlY3RvciBmb3IgdGhlIFUtcGF0Y2ggc3lzdGVtLgoKeDBfbWV0YSA8LSB1bmxpc3QobGFwcGx5KAogIHNlcV9sZW4oVSksIAogIGZ1bmN0aW9uKGkpeyAKICAgIGMocGF0Y2hQb3BTaXplW2ldIC0gaW5pdGlhbF9pbmZlY3RlZFtpXSwgaW5pdGlhbF9pbmZlY3RlZFtpXSwgMCwgMCwgcGF0Y2hQb3BTaXplW2ldKQogIH0KKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oaSkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgaSkpKQoKCiMgRGVmaW5lIHRoZSBzdGF0ZSBjaGFuZ2UgbWF0cml4IGZvciBhIHNpbmdsZSBwYXRjaApudV9tZXRhIDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwojIE1hc3MtYWN0aW9uCmFfbWV0YSA8LQogIHVubGlzdChsYXBwbHkoCiAgICBzZXFfbGVuKFUpLAogICAgZnVuY3Rpb24ocGF0Y2gpIHsKICAgICAgaSA8LSBwYXRjaAogICAgICBwYXRjaGVzIDwtIDE6VQogICAgICAjaiA8LSBpZiAocGF0Y2ggPT0gMSkgVSBlbHNlIHBhdGNoIC0gMQogICAgICBvdGhlcl9wYXRjaGVzIDwtIHBhdGNoZXNbLWldCiAgICAgIHBhdGNoX2JldGEgPC0gYygpCiAgICAgIGZvcihrIGluICgxOihVLTEpKSl7CiAgICAgICAgcGF0Y2hfYmV0YVtrXSA9IHBhc3RlMCgiKyhiZXRhXyIsIG90aGVyX3BhdGNoZXNba10saSwgIipJIiwgb3RoZXJfcGF0Y2hlc1trXSwgIi9OIiwgb3RoZXJfcGF0Y2hlc1trXSwgIikqUyIsIGkpCiAgICAgIH0KICAgICAgYygKICAgICAgICBwYXN0ZTAoIihiZXRhXyIsIGksIGksICIqSSIsIGksIi9OIiwgaSwgIikqUyIsaSwgcGFzdGUwKHBhdGNoX2JldGEsIGNvbGxhcHNlPSIiKSksICMgSW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJzaWdtYSpFIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCZWNvbWVzIGluZmVjaW91cwogICAgICAgIHBhc3RlMCgiZ2FtbWEqSSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgUmVjb3ZlcnkgZnJvbSBpbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoIm9tZWdhKlIiLCBpKSwgICAgICAgIyBMb3NzIG9mIGltbXVuaXR5CiAgICAgICAgcGFzdGUwKCJtdSpOIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRocwogICAgICAgIHBhc3RlMCgibXUqUyIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChTKQogICAgICAgIHBhc3RlMCgibXUqRSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChFKQogICAgICAgIHBhc3RlMCgibXUqSSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChJKQogICAgICAgIHBhc3RlMCgibXUqUiIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChSKQogICAgICAgIHBhc3RlMCgiYWxwaGEqSSIsIGkpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIGZyb20gaW5mZWN0aW9uCiAgICAgICAgCiAgICAgICkKICAgIH0KICApKQoKYGBgCgoKRGVmaW5lIGZ1bmN0aW9ucyBmb3IgY2FsY3VsYXRpbmcgUjAgZnJvbSBuZXh0LWdlbmVyYXRpb24gbWF0cml4CmBgYHtyfQojIENhbGN1bGF0ZSBSMCBmcm9tIE5HTQoKUjBuZ20gPC0gZnVuY3Rpb24obmV4dGdlbl9tYXRyaXgpIHsKICBlaWdlbnZhbHVlcyA9IGVpZ2VuKG5leHRnZW5fbWF0cml4LCBvbmx5LnZhbHVlcyA9IFQpCiAgUjAgPSBtYXgoYWJzKGVpZ2VudmFsdWVzJHZhbHVlcykpCiAgcmV0dXJuKFIwKQp9CgpiZXRhLm5nbSA8LSBmdW5jdGlvbihiZXRhX21hdHJpeCkgewogIGVpZ2VudmFsdWVzID0gZWlnZW4oYmV0YV9tYXRyaXgsIG9ubHkudmFsdWVzID0gVCkKICBiZXRhX25nbSA9IG1heChhYnMoZWlnZW52YWx1ZXMkdmFsdWVzKSkKICByZXR1cm4oYmV0YV9uZ20pCn0KYGBgCgoKCiMjIyBSdW4gTWV0YXBvcHVsYXRpb24gTW9kZWwKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YSA8LSBsaXN0KAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiMgRGVmaW5lIHRyYW5zbWlzc2lvbiB0ZXJtcyBhbmQgcG9wdWxhdGUgbmV4dC1nZW5lcmF0aW9uIG1hdHJpeApiZXRhIDwtIDAuNgoKbmV4dGdlbl9tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCmJldGFfbWF0cml4IDwtIG1hdHJpeChucm93ID0gVSwgbmNvbCA9IFUsIGRhdGEgPSAwKQoKCmZvcihpIGluIDE6VSl7CiAgZm9yKGogaW4gMTpVKXsKICAgIHBhcm1zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGksaSldXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuX21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfbWV0YSRnYW1tYSkKICAgIHBhcm1zX21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaSldXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl9tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc19tZXRhJGdhbW1hKQogICAgbmV4dGdlbl9tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc19tZXRhJGdhbW1hKQogICAgcGFybXNfbWV0YVtbcGFzdGUwKCJiZXRhXyIsaixqKV1dID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc19tZXRhJGdhbW1hKQogICAgYmV0YV9tYXRyaXhbaSxpXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhX21hdHJpeFtqLGldID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhX21hdHJpeFtpLGpdID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhX21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICB9CiAgcGFybXNfbWV0YVtbcGFzdGUwKCJOIiwgaSldXSA9IHBhdGNoUG9wU2l6ZVtpXQp9CmBgYAoKCmBgYHtyfQojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDI1KQpvdXRfbWV0YSA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIFBsb3QKcGxvdF9kYXRhX21ldGEgPC0gb3V0X21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGEgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDEsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgdGhlbWVfYncoKQpwbG90X21ldGEKCmdnc2F2ZShmaWxlbmFtZSA9ICJtZXRhX3Bsb3RfNy5wZGYiLCAKICAgICAgIHBsb3QgPSBwbG90X21ldGEsCiAgICAgICBkZXZpY2UgPSAicGRmIiwKICAgICAgIHdpZHRoID0gNywgCiAgICAgICBoZWlnaHQgPSA4LAogICAgICAgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL1Bsb3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMiKQpgYGAKCmBgYHtyfQojIyBUYWJsZSBzaG93aW5nIGV4dGluY3Rpb24vdHJhbnNtaXNzaW9uIGluZm8gZm9yIGVhY2ggcGF0Y2gKCmV4dGluY3RfZGF0YV9tZXRhIDwtIG91dF9tZXRhJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgc2xpY2VfbWF4KHQpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbihzdGF0ZT09IkkiICYgY291bnQgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGU9PSJJIiAmIGNvdW50ID09IDAgfiBGKSkgJT4lCiAgZHJvcF9uYSgpICU+JQogIHNlbGVjdChwYXRjaCwgY291bnQsIHBlcnNpc3QpCmV4dGluY3RfZGF0YV9tZXRhCmBgYAoKCmBgYHtyfQpiZXRhX21ldGEgPC0gYmV0YS5uZ20oYmV0YV9tYXRyaXgpCnBhc3RlMCgiQmV0YSBmb3Igd2hvbGUgc3lzdGVtID0gIiwgYmV0YV9tZXRhKQoKClIwX21ldGEgPC0gUjBuZ20obmV4dGdlbl9tYXRyaXgpCnBhc3RlMCgiUjAgPSAiLCBSMF9tZXRhKQoKCnBhc3RlMCgiQWN0dWFsIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgZW5kIG9mIHNpbSA9ICIsIHN1bShleHRpbmN0X2RhdGFfbWV0YSRjb3VudCkpCiAjIFRvdGFsIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgdGhlIGVuZCBvZiBzaW0gYWNyb3NzIGFsbCBwYXRjaGVzCgpzaW1fZW5kcG9pbnRfbWV0YSA8LSBhc190aWJibGUob3V0X21ldGEkZGF0YSkgJT4lCiAgc2xpY2VfbWF4KHQpICU+JQogIGRpc3RpbmN0KCkKCgpwYXN0ZTAoIkRpZCBzaW11bGF0aW9uIHJ1biByZWFjaCBmaW5hbCBlbmRwb2ludD8iKQppZiAoc2ltX2VuZHBvaW50X21ldGEkdCA+PSB0ZikgewogIHByaW50KCJZZXMiKQp9IGVsc2UgewogIHByaW50KCJObyIpfQoKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YSA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdChsYXBwbHkoCiAgc2VxX2xlbihVKSwgCiAgZnVuY3Rpb24oeCl7IAogICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgfQopKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCiAgCiAgb3V0XzEwMF9tZXRhIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhIDwtIG91dF8xMDBfbWV0YSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhW1tpXV0gPC0gc2ltX2RhdGFfbWV0YQp9CgpzaW1fb3V0cHV0X21ldGEgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YSA8LSBzaW1fb3V0cHV0X21ldGEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGEKYGBgCgoKCmBgYHtyfQojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YSA8LSBzaW1fb3V0cHV0X21ldGEgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnlfbWV0YQpgYGAKCgoKIyMjIFZhcnlpbmcgd2FpbmluZyBpbW11bml0eSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KIyMjIyAwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8wIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8wJG9tZWdhIDwtIDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzAgPC0gb3V0X21ldGFfMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8wIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8wIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8wLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8wIDwtIG91dF8xMDBfbWV0YV8wJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMAp9CgpzaW1fb3V0cHV0X21ldGFfMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8wKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMCA8LSBzaW1fb3V0cHV0X21ldGFfMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8wCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8wIDwtIHNpbV9vdXRwdXRfbWV0YV8wICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMCkKc2ltX3N1bW1hcnlfbWV0YV8wCmBgYAoKCgojIyMjIDEgRGF5CmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMSA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMSRvbWVnYSA8LSAxCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8xIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xIDwtIG91dF9tZXRhXzEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMSA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzEKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzEgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8xIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMSA8LSBvdXRfMTAwX21ldGFfMSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzFbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzEKfQoKc2ltX291dHB1dF9tZXRhXzEgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzEgPC0gc2ltX291dHB1dF9tZXRhXzEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMSA8LSBzaW1fb3V0cHV0X21ldGFfMSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxKQpzaW1fc3VtbWFyeV9tZXRhXzEKYGBgCgoKCgojIyMjIDMgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzMgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzMkb21lZ2EgPC0gMS8zCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8zIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8zIDwtIG91dF9tZXRhXzMkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMyA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzMsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzMKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8zIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzMgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMyA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzMgPC0gb3V0XzEwMF9tZXRhXzMkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8zW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8zCn0KCnNpbV9vdXRwdXRfbWV0YV8zIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzMpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8zIDwtIHNpbV9vdXRwdXRfbWV0YV8zICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzMKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzMgPC0gc2ltX291dHB1dF9tZXRhXzMgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zKQpzaW1fc3VtbWFyeV9tZXRhXzMKYGBgCgoKCgoKCiMjIyMgNyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNyA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfNyRvbWVnYSA8LSAxLzcKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzcgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfNywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzcgPC0gb3V0X21ldGFfNyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV83IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfNywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNwpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzcgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfNyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV83IDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfNyA8LSBvdXRfMTAwX21ldGFfNyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzdbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzcKfQoKc2ltX291dHB1dF9tZXRhXzcgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzcgPC0gc2ltX291dHB1dF9tZXRhXzcgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfNyA8LSBzaW1fb3V0cHV0X21ldGFfNyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcpCnNpbV9zdW1tYXJ5X21ldGFfNwpgYGAKCgoKIyMjIyAxMCBEYXlzCgpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzEwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xMCRvbWVnYSA8LSAxLzEwCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzEwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMTAgPC0gb3V0X21ldGFfMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8xMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzEwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzEwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzEwIDwtIG91dF8xMDBfbWV0YV8xMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzEwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8xMAp9CgpzaW1fb3V0cHV0X21ldGFfMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8xMCA8LSBzaW1fb3V0cHV0X21ldGFfMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTAgPC0gc2ltX291dHB1dF9tZXRhXzEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTQpCnNpbV9zdW1tYXJ5X21ldGFfMTAKYGBgCgoKIyMjIyAyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMjAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzIwJG9tZWdhIDwtIDEvMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzIwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMjAgPC0gb3V0X21ldGFfMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8yMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzIwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzIwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzIwIDwtIG91dF8xMDBfbWV0YV8yMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzIwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8yMAp9CgpzaW1fb3V0cHV0X21ldGFfMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMjApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8yMCA8LSBzaW1fb3V0cHV0X21ldGFfMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMjAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzIwIDwtIHNpbV9vdXRwdXRfbWV0YV8yMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV9tZXRhXzIwCmBgYAoKCgoKCgojIyMjIDMwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8zMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMzAkb21lZ2EgPC0gMS8zMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMzAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8zMCA8LSBvdXRfbWV0YV8zMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8zMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzMwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8zMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMzAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMzAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMzAgPC0gb3V0XzEwMF9tZXRhXzMwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMzBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzMwCn0KCnNpbV9vdXRwdXRfbWV0YV8zMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8zMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzMwIDwtIHNpbV9vdXRwdXRfbWV0YV8zMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8zMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMzAgPC0gc2ltX291dHB1dF9tZXRhXzMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zMCkKc2ltX3N1bW1hcnlfbWV0YV8zMApgYGAKCgoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNDAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzQwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzQwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNDAgPC0gb3V0X21ldGFfNDAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfNDAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV80MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNDAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzQwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzQwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzQwIDwtIG91dF8xMDBfbWV0YV80MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzQwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV80MAp9CgpzaW1fb3V0cHV0X21ldGFfNDAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNDApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV80MCA8LSBzaW1fb3V0cHV0X21ldGFfNDAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNDAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzQwIDwtIHNpbV9vdXRwdXRfbWV0YV80MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV9tZXRhXzQwCmBgYAoKCgoKCgoKIyMjIyA1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfNTAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzUwJG9tZWdhIDwtIDEvNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzUwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfNTAgPC0gb3V0X21ldGFfNTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV81MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfNTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzUwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzUwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzUwIDwtIG91dF8xMDBfbWV0YV81MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzUwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV81MAp9CgpzaW1fb3V0cHV0X21ldGFfNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfNTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV81MCA8LSBzaW1fb3V0cHV0X21ldGFfNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfNTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzUwIDwtIHNpbV9vdXRwdXRfbWV0YV81MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzUwKQpzaW1fc3VtbWFyeV9tZXRhXzUwCmBgYAoKCgoKCiMjIyMgNjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzYwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV82MCRvbWVnYSA8LSAxLzYwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV82MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV82MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzYwIDwtIG91dF9tZXRhXzYwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzYwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfNjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzYwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV82MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV82MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV82MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV82MCA8LSBvdXRfMTAwX21ldGFfNjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV82MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfNjAKfQoKc2ltX291dHB1dF9tZXRhXzYwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzYwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfNjAgPC0gc2ltX291dHB1dF9tZXRhXzYwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzYwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV82MCA8LSBzaW1fb3V0cHV0X21ldGFfNjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS82MCkKc2ltX3N1bW1hcnlfbWV0YV82MApgYGAKCgoKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzcwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV83MCRvbWVnYSA8LSAxLzcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV83MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV83MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzcwIDwtIG91dF9tZXRhXzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV83MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV83MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV83MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV83MCA8LSBvdXRfMTAwX21ldGFfNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV83MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfNzAKfQoKc2ltX291dHB1dF9tZXRhXzcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfNzAgPC0gc2ltX291dHB1dF9tZXRhXzcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV83MCA8LSBzaW1fb3V0cHV0X21ldGFfNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83MCkKc2ltX3N1bW1hcnlfbWV0YV83MApgYGAKCgojIyMjIDgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV84MCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfODAkb21lZ2EgPC0gMS84MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfODAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV84MCA8LSBvdXRfbWV0YV84MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV84MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV84MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfODAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfODAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV84MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfODAgPC0gb3V0XzEwMF9tZXRhXzgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfODBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzgwCn0KCnNpbV9vdXRwdXRfbWV0YV84MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV84MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzgwIDwtIHNpbV9vdXRwdXRfbWV0YV84MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV84MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfODAgPC0gc2ltX291dHB1dF9tZXRhXzgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvODApCnNpbV9zdW1tYXJ5X21ldGFfODAKYGBgCgoKCiMjIyMgOTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzkwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV85MCRvbWVnYSA8LSAxLzkwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV85MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV85MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzkwIDwtIG91dF9tZXRhXzkwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzkwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfOTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzkwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV85MCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV85MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV85MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzkwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV85MCA8LSBvdXRfMTAwX21ldGFfOTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV85MFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfOTAKfQoKc2ltX291dHB1dF9tZXRhXzkwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzkwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfOTAgPC0gc2ltX291dHB1dF9tZXRhXzkwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzkwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV85MCA8LSBzaW1fb3V0cHV0X21ldGFfOTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS85MCkKc2ltX3N1bW1hcnlfbWV0YV85MApgYGAKCgoKCgoKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xODAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjApCm91dF9tZXRhXzE4MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8xODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xODAgPC0gb3V0X21ldGFfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzE4MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzE4MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8xODAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzE4MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzE4MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTgwIDwtIG91dF8xMDBfbWV0YV8xODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8xODBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzE4MAp9CgpzaW1fb3V0cHV0X21ldGFfMTgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzE4MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzE4MCA8LSBzaW1fb3V0cHV0X21ldGFfMTgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzE4MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTgwIDwtIHNpbV9vdXRwdXRfbWV0YV8xODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xODApCnNpbV9zdW1tYXJ5X21ldGFfMTgwCmBgYAoKIyMjIyAxMTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzExMCA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMTEwJG9tZWdhIDwtIDEvMTEwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8xMTAgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMTEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMTEwIDwtIG91dF9tZXRhXzExMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8xMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8xMTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzExMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMTEwIDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzExMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8xMTAgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8xMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzExMCA8LSBvdXRfMTAwX21ldGFfMTEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMTEwW1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8xMTAKfQoKc2ltX291dHB1dF9tZXRhXzExMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8xMTApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8xMTAgPC0gc2ltX291dHB1dF9tZXRhXzExMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8xMTAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzExMCA8LSBzaW1fb3V0cHV0X21ldGFfMTEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTEwKQpzaW1fc3VtbWFyeV9tZXRhXzExMApgYGAKCiMjIyMgMTIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8xMjAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzEyMCRvbWVnYSA8LSAxLzEyMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMTIwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzEyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzEyMCA8LSBvdXRfbWV0YV8xMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMTIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMTIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8xMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzEyMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8xMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMTIwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8xMjAgPC0gb3V0XzEwMF9tZXRhXzEyMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzEyMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMTIwCn0KCnNpbV9vdXRwdXRfbWV0YV8xMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMTIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMTIwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMTIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8xMjAgPC0gc2ltX291dHB1dF9tZXRhXzEyMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEyMCkKc2ltX3N1bW1hcnlfbWV0YV8xMjAKYGBgCgojIyMjIDEzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMTMwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xMzAkb21lZ2EgPC0gMS8xMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzEzMCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8xMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xMzAgPC0gb3V0X21ldGFfMTMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzEzMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzEzMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8xMzAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzEzMCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzEzMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTMwIDwtIG91dF8xMDBfbWV0YV8xMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8xMzBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzEzMAp9CgpzaW1fb3V0cHV0X21ldGFfMTMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzEzMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzEzMCA8LSBzaW1fb3V0cHV0X21ldGFfMTMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzEzMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTMwIDwtIHNpbV9vdXRwdXRfbWV0YV8xMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMzApCnNpbV9zdW1tYXJ5X21ldGFfMTMwCmBgYAoKCgoKCgoKCgoKCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMTUwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8xNTAkb21lZ2EgPC0gMS8xNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzE1MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8xNTAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8xNTAgPC0gb3V0X21ldGFfMTUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzE1MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzE1MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMTUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8xNTAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMTUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzE1MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzE1MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMTUwIDwtIG91dF8xMDBfbWV0YV8xNTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8xNTBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzE1MAp9CgpzaW1fb3V0cHV0X21ldGFfMTUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzE1MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzE1MCA8LSBzaW1fb3V0cHV0X21ldGFfMTUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzE1MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfbWV0YV8xNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5X21ldGFfMTUwCmBgYAoKCiMjIyMgMjIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfbWV0YV8yMjAgPC0gcGFybXNfbWV0YQpwYXJtc19tZXRhXzIyMCRvbWVnYSA8LSAxLzIyMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0X21ldGFfMjIwIDwtIHNzYSgKICB4MCA9IHgwX21ldGEsCiAgYSA9IGFfbWV0YSwKICBudSA9IG51X21ldGEsCiAgcGFybXMgPSBwYXJtc19tZXRhXzIyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9tZXRhXzIyMCA8LSBvdXRfbWV0YV8yMjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90X21ldGFfMjIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX21ldGFfMjIwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfbWV0YV8yMjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9tZXRhXzIyMCA8LSBsaXN0KCkKc2ltX2xpc3RfbWV0YV8yMjAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemUgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwX21ldGFfMjIwIDwtIHNzYSgKICAgIHgwID0geDBfbWV0YSwKICAgIGEgPSBhX21ldGEsCiAgICBudSA9IG51X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zX21ldGFfMjIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfbWV0YV8yMjAgPC0gb3V0XzEwMF9tZXRhXzIyMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF9tZXRhXzIyMFtbaV1dIDwtIHNpbV9kYXRhX21ldGFfMjIwCn0KCnNpbV9vdXRwdXRfbWV0YV8yMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0X21ldGFfMjIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X21ldGFfMjIwIDwtIHNpbV9vdXRwdXRfbWV0YV8yMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0X21ldGFfMjIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfbWV0YV8yMjAgPC0gc2ltX291dHB1dF9tZXRhXzIyMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIyMCkKc2ltX3N1bW1hcnlfbWV0YV8yMjAKYGBgCgoKCgojIyMjIDI3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zX21ldGFfMjcwIDwtIHBhcm1zX21ldGEKcGFybXNfbWV0YV8yNzAkb21lZ2EgPC0gMS8yNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF9tZXRhXzI3MCA8LSBzc2EoCiAgeDAgPSB4MF9tZXRhLAogIGEgPSBhX21ldGEsCiAgbnUgPSBudV9tZXRhLAogIHBhcm1zID0gcGFybXNfbWV0YV8yNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfbWV0YV8yNzAgPC0gb3V0X21ldGFfMjcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF9tZXRhXzI3MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9tZXRhXzI3MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90X21ldGFfMjcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfbWV0YV8yNzAgPC0gbGlzdCgpCnNpbV9saXN0X21ldGFfMjcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF9tZXRhXzI3MCA8LSBzc2EoCiAgICB4MCA9IHgwX21ldGEsCiAgICBhID0gYV9tZXRhLAogICAgbnUgPSBudV9tZXRhLAogICAgcGFybXMgPSBwYXJtc19tZXRhXzI3MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhX21ldGFfMjcwIDwtIG91dF8xMDBfbWV0YV8yNzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfbWV0YV8yNzBbW2ldXSA8LSBzaW1fZGF0YV9tZXRhXzI3MAp9CgpzaW1fb3V0cHV0X21ldGFfMjcwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9tZXRhXzI3MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9tZXRhXzI3MCA8LSBzaW1fb3V0cHV0X21ldGFfMjcwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF9tZXRhXzI3MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X21ldGFfMjcwIDwtIHNpbV9vdXRwdXRfbWV0YV8yNzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yNzApCnNpbV9zdW1tYXJ5X21ldGFfMjcwCmBgYAoKIyMjIyAzNjUgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc19tZXRhXzM2NSA8LSBwYXJtc19tZXRhCnBhcm1zX21ldGFfMzY1JG9tZWdhIDwtIDEvMzY1CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfbWV0YV8zNjUgPC0gc3NhKAogIHgwID0geDBfbWV0YSwKICBhID0gYV9tZXRhLAogIG51ID0gbnVfbWV0YSwKICBwYXJtcyA9IHBhcm1zX21ldGFfMzY1LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX21ldGFfMzY1IDwtIG91dF9tZXRhXzM2NSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfbWV0YV8zNjUgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfbWV0YV8zNjUsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF9tZXRhXzM2NQpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X21ldGFfMzY1IDwtIGxpc3QoKQpzaW1fbGlzdF9tZXRhXzM2NSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZSA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZVt4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZVt4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfbWV0YV8zNjUgPC0gc3NhKAogICAgeDAgPSB4MF9tZXRhLAogICAgYSA9IGFfbWV0YSwKICAgIG51ID0gbnVfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfbWV0YV8zNjUsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9tZXRhXzM2NSA8LSBvdXRfMTAwX21ldGFfMzY1JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X21ldGFfMzY1W1tpXV0gPC0gc2ltX2RhdGFfbWV0YV8zNjUKfQoKc2ltX291dHB1dF9tZXRhXzM2NSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfbWV0YV8zNjUpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfbWV0YV8zNjUgPC0gc2ltX291dHB1dF9tZXRhXzM2NSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfbWV0YV8zNjUKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV9tZXRhXzM2NSA8LSBzaW1fb3V0cHV0X21ldGFfMzY1ICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzY1KQpzaW1fc3VtbWFyeV9tZXRhXzM2NQpgYGAKClNpbmdsZQoKCgoKCiMjIyMgUmVzdWx0cwpgYGB7cn0Kd2FuaW5nX3Jlc3VsdHNfNyA8LSBzaW1fc3VtbWFyeV9tZXRhICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzMpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzcpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8yMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzQwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV81MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfNjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzcwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV84MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfOTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEwMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8xMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzEzMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMTUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfbWV0YV8yMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV9tZXRhXzI3MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5X21ldGFfMzY1KSAlPiUKICBtdXRhdGUoaW1tdW5pdHlfZHVyYXRpb24gPSAxL29tZWdhKSAlPiUKICBhcnJhbmdlKGltbXVuaXR5X2R1cmF0aW9uKSAlPiUKICBtdXRhdGUobW9kZWwgPSAibWV0YSIsCiAgICAgICAgIHBhdGNoZXMgPSA3KQoKd3JpdGVfY3N2KHdhbmluZ19yZXN1bHRzXzcsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfNy5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfNwoKYGBgCgpgYGB7cn0KZ2dwbG90KHdhbmluZ19yZXN1bHRzXzcsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgoKCgojIyAzLVBhdGNoIE1ldGFwb3B1bGF0aW9uIE1vZGVsIAoKVGhlIHNhbWUgbWV0YXBvcHVsYXRpb24gU0VJUlMgbW9kZWwgd2FzIHRoZW4gdXNlZCB0byBtb2RlbCB0aGUgZHluYW1pY3Mgb2YgcGVyc2lzdGVuY2UgaW4gYSAzLXBhdGNoIHN5c3RlbSBhbmQgdW5kZXJzdGFuZCB0aGUgZWZmZWN0IG9mIHdhbmluZyBpbW11bml0eS4KCiMjI1NldC11cAoKYGBge3J9CiMgRGVmaW5lIFBhcmFtZW50ZXJzCnBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBQYXRjaCBzaXplClUgPC0gbGVuZ3RoKHBhdGNoUG9wU2l6ZV8zKSAgICAgICAgICAgICAgICAgICAgIyBOdW1iZXIgb2YgcGF0Y2hlcwppbml0aWFsX2luZmVjdGVkIDwtICBhcy52ZWN0b3Iocm11bHRpbm9tKDEsIDEsIHJlcCgwLjUsIFUpKSkgICAjIEluaXRpYWwgaW5mZWN0ZWQgKGluaXRpYWwgaW5mZWN0ZWQgcGF0Y2ggcmFuZG9tbHkgZ2VuZXJhdGVkKQppbml0aWFsX2luZmVjdGVkX3BhdGNoIDwtIHdoaWNoKGluaXRpYWxfaW5mZWN0ZWQgPiAwKQpzaW1OYW1lIDwtICJTSVJTIG1ldGFwb3B1bGF0aW9uIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBGaW5hbCB0aW1lCgojIEFndGEgSHVudGVyLUdhdGhlcmVyIGNvbnRhY3QgcmF0ZXMKd2l0aGluX3BvcF9jb250YWN0ID0gMQpiZXR3ZWVuX3BvcF9jb250YWN0ID0gMC41L1UgICAgICMgbm9ybWFsaXNlZCBieSBudW1iZXIgb2YgcGF0Y2hlcyAKCiNDcmVhdGUgdGhlIG5hbWVkIGluaXRpYWwgc3RhdGUgdmVjdG9yIGZvciB0aGUgVS1wYXRjaCBzeXN0ZW0uCgp4MF8zX21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbihpKXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8zW2ldIC0gaW5pdGlhbF9pbmZlY3RlZFtpXSwgaW5pdGlhbF9pbmZlY3RlZFtpXSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbaV0pCiAgfQopKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKGkpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIGkpKSkKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnVfM19tZXRhIDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwojIE1hc3MtYWN0aW9uCmFfM19tZXRhIDwtCiAgdW5saXN0KGxhcHBseSgKICAgIHNlcV9sZW4oVSksCiAgICBmdW5jdGlvbihwYXRjaCkgewogICAgICBpIDwtIHBhdGNoCiAgICAgIHBhdGNoZXMgPC0gMTpVCiAgICAgICNqIDwtIGlmIChwYXRjaCA9PSAxKSBVIGVsc2UgcGF0Y2ggLSAxCiAgICAgIG90aGVyX3BhdGNoZXMgPC0gcGF0Y2hlc1staV0KICAgICAgcGF0Y2hfYmV0YSA8LSBjKCkKICAgICAgZm9yKGsgaW4gKDE6KFUtMSkpKXsKICAgICAgICBwYXRjaF9iZXRhW2tdID0gcGFzdGUwKCIrKGJldGFfIiwgb3RoZXJfcGF0Y2hlc1trXSxpLCAiKkkiLCBvdGhlcl9wYXRjaGVzW2tdLCAiL04iLCBvdGhlcl9wYXRjaGVzW2tdLCAiKSpTIiwgaSkKICAgICAgfQogICAgICBjKAogICAgICAgIHBhc3RlMCgiKGJldGFfIiwgaSwgaSwgIipJIiwgaSwiL04iLCBpLCAiKSpTIixpLCBwYXN0ZTAocGF0Y2hfYmV0YSwgY29sbGFwc2U9IiIpKSwgIyBJbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoInNpZ21hKkUiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJlY29tZXMgaW5mZWNpb3VzCiAgICAgICAgcGFzdGUwKCJnYW1tYSpJIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZWNvdmVyeSBmcm9tIGluZmVjdGlvbgogICAgICAgIHBhc3RlMCgib21lZ2EqUiIsIGkpLCAgICAgICAjIExvc3Mgb2YgaW1tdW5pdHkKICAgICAgICBwYXN0ZTAoIm11Kk4iLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGhzCiAgICAgICAgcGFzdGUwKCJtdSpTIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFMpCiAgICAgICAgcGFzdGUwKCJtdSpFIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEUpCiAgICAgICAgcGFzdGUwKCJtdSpJIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEkpCiAgICAgICAgcGFzdGUwKCJtdSpSIiwgaSksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFIpCiAgICAgICAgcGFzdGUwKCJhbHBoYSpJIiwgaSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgZnJvbSBpbmZlY3Rpb24KICAgICAgICAKICAgICAgKQogICAgfQogICkpCgpgYGAKCgoKIyMjIFJ1biBNZXRhcG9wdWxhdGlvbiBNb2RlbApgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGEgPC0gbGlzdCgKICBzaWdtYSA9IDAuMTc1LCAgICAgICAgICAgICAgICAgICAgICAgICAgIyBFIHRvIEkgcmF0ZQogIGdhbW1hID0gMC4yLCAgICAgICAgICAgICAgICAgICAgICAgICAgICMgSSB0byBSIHJhdGUKICBvbWVnYSA9IDEvMTAwLCAgICAgICAgICAgICAgICAgICAgICAgICAjIFIgdG8gUyByYXRlCiAgbXUgPSBkZW1vX3N1bSRCaXJ0aF9yYXRlX2RhaWx5X01lYW4sICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGgvZGVhdGggcmF0ZSBwZXIgcGVyc29uIHBlciBkYXkKICBhbHBoYSA9IDEvMTAwMCkgCgojIERlZmluZSB0cmFuc21pc3Npb24gdGVybXMgYW5kIHBvcHVsYXRlIG5leHQtZ2VuZXJhdGlvbiBtYXRyaXgKYmV0YSA8LSAwLjYKCm5leHRnZW5fM19tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCmJldGFfM19tYXRyaXggPC0gbWF0cml4KG5yb3cgPSBVLCBuY29sID0gVSwgZGF0YSA9IDApCgoKZm9yKGkgaW4gMTpVKXsKICBmb3IoaiBpbiAxOlUpewogICAgcGFybXNfM19tZXRhW1twYXN0ZTAoImJldGFfIixpLGkpXV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8zX21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfM19tZXRhJGdhbW1hKQogICAgcGFybXNfM19tZXRhW1twYXN0ZTAoImJldGFfIixqLGkpXV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fM19tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YSooMS9wYXJtc18zX21ldGEkZ2FtbWEpCiAgICBuZXh0Z2VuXzNfbWF0cml4W2ksal0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfM19tZXRhJGdhbW1hKQogICAgcGFybXNfM19tZXRhW1twYXN0ZTAoImJldGFfIixqLGopXV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8zX21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfM19tZXRhJGdhbW1hKQogICAgYmV0YV8zX21hdHJpeFtpLGldID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEKICAgIGJldGFfM19tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8zX21hdHJpeFtpLGpdID0gYmV0d2Vlbl9wb3BfY29udGFjdCpiZXRhCiAgICBiZXRhXzNfbWF0cml4W2osal0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogIH0KICBwYXJtc18zX21ldGFbW3Bhc3RlMCgiTiIsIGkpXV0gPSBwYXRjaFBvcFNpemVfM1tpXQp9CmBgYAoKCmBgYHtyfQojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDI1KQpvdXRfM19tZXRhIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBQbG90CnBsb3RfZGF0YV8zX21ldGEgPC0gb3V0XzNfbWV0YSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDEsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YQoKZ2dzYXZlKGZpbGVuYW1lID0gIm1ldGFfcGxvdF8zLnBkZiIsIAogICAgICAgcGxvdCA9IHBsb3RfM19tZXRhLAogICAgICAgZGV2aWNlID0gInBkZiIsCiAgICAgICB3aWR0aCA9IDcsIAogICAgICAgaGVpZ2h0ID0gOCwKICAgICAgIHBhdGggPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9QbG90cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzIikKYGBgCgpgYGB7cn0KIyMgVGFibGUgc2hvd2luZyBleHRpbmN0aW9uL3RyYW5zbWlzc2lvbiBpbmZvIGZvciBlYWNoIHBhdGNoCgpleHRpbmN0X2RhdGFfM19tZXRhIDwtIG91dF8zX21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHN0YXRlPT0iSSIgJiBjb3VudCA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZT09IkkiICYgY291bnQgPT0gMCB+IEYpKSAlPiUKICBkcm9wX25hKCkgJT4lCiAgc2VsZWN0KHBhdGNoLCBjb3VudCwgcGVyc2lzdCkKZXh0aW5jdF9kYXRhXzNfbWV0YQpgYGAKCgpgYGB7cn0KYmV0YV8zX21ldGEgPC0gYmV0YS5uZ20oYmV0YV8zX21hdHJpeCkKcGFzdGUwKCJCZXRhIGZvciB3aG9sZSBzeXN0ZW0gPSAiLCBiZXRhXzNfbWV0YSkKCgpSMF8zX21ldGEgPC0gUjBuZ20obmV4dGdlbl8zX21hdHJpeCkKcGFzdGUwKCJSMCA9ICIsIFIwXzNfbWV0YSkKCgpwYXN0ZTAoIkFjdHVhbCBudW1iZXIgb2YgaW5mZWN0ZWRzIGF0IGVuZCBvZiBzaW0gPSAiLCBzdW0oZXh0aW5jdF9kYXRhXzNfbWV0YSRjb3VudCkpCiAjIFRvdGFsIG51bWJlciBvZiBpbmZlY3RlZHMgYXQgdGhlIGVuZCBvZiBzaW0gYWNyb3NzIGFsbCBwYXRjaGVzCgpzaW1fZW5kcG9pbnRfM19tZXRhIDwtIGFzX3RpYmJsZShvdXRfM19tZXRhJGRhdGEpICU+JQogIHNsaWNlX21heCh0KSAlPiUKICBkaXN0aW5jdCgpCgoKcGFzdGUwKCJEaWQgc2ltdWxhdGlvbiBydW4gcmVhY2ggZmluYWwgZW5kcG9pbnQ/IikKaWYgKHNpbV9lbmRwb2ludF8zX21ldGEkdCA+PSB0ZikgewogIHByaW50KCJZZXMiKQp9IGVsc2UgewogIHByaW50KCJObyIpfQoKYGBgCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGEgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbih4KXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgfQopKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKICAKICBvdXRfMTAwXzNfbWV0YSA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGEgPC0gb3V0XzEwMF8zX21ldGEkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhCn0KCnNpbV9vdXRwdXRfM19tZXRhIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhIDwtIHNpbV9vdXRwdXRfM19tZXRhICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGEKYGBgCgoKCmBgYHtyfQojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhIDwtIHNpbV9vdXRwdXRfM19tZXRhICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMDApCnNpbV9zdW1tYXJ5XzNfbWV0YQpgYGAKCiMjIyBWYXJ5aW5nIHdhaW5pbmcgaW1tdW5pdHkgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8wIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMCRvbWVnYSA8LSAwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8wLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8wIDwtIG91dF8zX21ldGFfMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8wIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8wIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8wLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzAgPC0gb3V0XzEwMF8zX21ldGFfMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8wCn0KCnNpbV9vdXRwdXRfM19tZXRhXzAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8wKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8wIDwtIHNpbV9vdXRwdXRfM19tZXRhXzAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8wCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzAgPC0gc2ltX291dHB1dF8zX21ldGFfMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDApCnNpbV9zdW1tYXJ5XzNfbWV0YV8wCmBgYAoKCgojIyMjIDEgRGF5CmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMSRvbWVnYSA8LSAxCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzEgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xIDwtIG91dF8zX21ldGFfMSRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzEgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMQpgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8xIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzEgPC0gb3V0XzEwMF8zX21ldGFfMSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMVtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xCn0KCnNpbV9vdXRwdXRfM19tZXRhXzEgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8xKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xIDwtIHNpbV9vdXRwdXRfM19tZXRhXzEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8xCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzEgPC0gc2ltX291dHB1dF8zX21ldGFfMSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxKQpzaW1fc3VtbWFyeV8zX21ldGFfMQpgYGAKCgoKCiMjIyMgMyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8zIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMyRvbWVnYSA8LSAxLzMKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMyA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzMgPC0gb3V0XzNfbWV0YV8zJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMyA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMywgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8zCmBgYAoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8zIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8zIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8zLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzMgPC0gb3V0XzEwMF8zX21ldGFfMyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfM1tbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8zCn0KCnNpbV9vdXRwdXRfM19tZXRhXzMgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8zKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8zIDwtIHNpbV9vdXRwdXRfM19tZXRhXzMgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8zCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzMgPC0gc2ltX291dHB1dF8zX21ldGFfMyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMpCnNpbV9zdW1tYXJ5XzNfbWV0YV8zCmBgYAoKCgoKCgojIyMjIDcgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfNyA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzckb21lZ2EgPC0gMS83CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzcgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV83LAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV83IDwtIG91dF8zX21ldGFfNyRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzcgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzcsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfNwpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfNyA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzcgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfNyA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfNywKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV83IDwtIG91dF8xMDBfM19tZXRhXzckZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzdbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfNwp9CgpzaW1fb3V0cHV0XzNfbWV0YV83IDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfNykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfNyA8LSBzaW1fb3V0cHV0XzNfbWV0YV83ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfNwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV83IDwtIHNpbV9vdXRwdXRfM19tZXRhXzcgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83KQpzaW1fc3VtbWFyeV8zX21ldGFfNwpgYGAKCgoKIyMjIyAxMCBEYXlzCgpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMTAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xMCRvbWVnYSA8LSAxLzEwCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTAgPC0gb3V0XzNfbWV0YV8xMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8xMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzEwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8xMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xMCA8LSBvdXRfMTAwXzNfbWV0YV8xMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMTBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTAKfQoKc2ltX291dHB1dF8zX21ldGFfMTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8xMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTAgPC0gc2ltX291dHB1dF8zX21ldGFfMTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE0KQpzaW1fc3VtbWFyeV8zX21ldGFfMTAKYGBgCgoKIyMjIyAyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8yMCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzIwJG9tZWdhIDwtIDEvMjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMjAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8yMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMjAgPC0gb3V0XzNfbWV0YV8yMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8yMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8yMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV8yMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzIwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzIwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV8yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8yMCA8LSBvdXRfMTAwXzNfbWV0YV8yMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfMjBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMjAKfQoKc2ltX291dHB1dF8zX21ldGFfMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8yMCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8yMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV8zX21ldGFfMjAKYGBgCgoKCgoKCiMjIyMgMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMzAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8zMCRvbWVnYSA8LSAxLzMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzMwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzMwIDwtIG91dF8zX21ldGFfMzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8zMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMzAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV8zMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8zMCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfMzAgPC0gb3V0XzEwMF8zX21ldGFfMzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzMwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzMwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzMwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzMwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzMwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfMzAgPC0gc2ltX291dHB1dF8zX21ldGFfMzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMwKQpzaW1fc3VtbWFyeV8zX21ldGFfMzAKYGBgCgoKCiMjIyMgNDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfNDAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV80MCRvbWVnYSA8LSAxLzQwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzQwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfNDAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfM19tZXRhXzQwIDwtIG91dF8zX21ldGFfNDAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV80MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8zX21ldGFfNDAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfNDAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfNDAgPC0gbGlzdCgpCnNpbV9saXN0XzNfbWV0YV80MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV80MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX21ldGFfNDAgPC0gb3V0XzEwMF8zX21ldGFfNDAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzQwW1tpXV0gPC0gc2ltX2RhdGFfM19tZXRhXzQwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzQwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfNDApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfM19tZXRhXzQwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzQwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfNDAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zX21ldGFfNDAgPC0gc2ltX291dHB1dF8zX21ldGFfNDAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS80MCkKc2ltX3N1bW1hcnlfM19tZXRhXzQwCmBgYAoKCgoKCgoKIyMjIyA1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV81MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzUwJG9tZWdhIDwtIDEvNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfNTAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV81MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfNTAgPC0gb3V0XzNfbWV0YV81MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzUwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV81MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV81MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV81MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzUwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV81MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV81MCA8LSBvdXRfMTAwXzNfbWV0YV81MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfNTBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfNTAKfQoKc2ltX291dHB1dF8zX21ldGFfNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfNTAgPC0gc2ltX291dHB1dF8zX21ldGFfNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV81MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV81MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzUwKQpzaW1fc3VtbWFyeV8zX21ldGFfNTAKYGBgCgoKCgoKIyMjIyA2MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV82MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzYwJG9tZWdhIDwtIDEvNjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfNjAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV82MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfNjAgPC0gb3V0XzNfbWV0YV82MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzYwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV82MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV82MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV82MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzYwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzYwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV82MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV82MCA8LSBvdXRfMTAwXzNfbWV0YV82MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfNjBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfNjAKfQoKc2ltX291dHB1dF8zX21ldGFfNjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV82MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfNjAgPC0gc2ltX291dHB1dF8zX21ldGFfNjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV82MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV82MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV82MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzYwKQpzaW1fc3VtbWFyeV8zX21ldGFfNjAKYGBgCgoKCgojIyMjIDcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzcwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfNzAkb21lZ2EgPC0gMS83MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV83MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzcwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV83MCA8LSBvdXRfM19tZXRhXzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfNzAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzcwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzcwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfNzAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfNzAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzcwIDwtIG91dF8xMDBfM19tZXRhXzcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV83MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV83MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV83MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzcwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV83MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV83MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzcwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzcwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNzApCnNpbV9zdW1tYXJ5XzNfbWV0YV83MApgYGAKCgojIyMjIDgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfM19tZXRhXzgwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfODAkb21lZ2EgPC0gMS84MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzNfbWV0YV84MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV84MCA8LSBvdXRfM19tZXRhXzgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfODAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzgwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfM19tZXRhXzgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzgwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfODAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMywgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8zX21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfM19tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8zX21ldGFfODAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzgwIDwtIG91dF8xMDBfM19tZXRhXzgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV84MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV84MAp9CgpzaW1fb3V0cHV0XzNfbWV0YV84MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV84MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV84MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzgwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvODApCnNpbV9zdW1tYXJ5XzNfbWV0YV84MApgYGAKCgoKIyMjIyA5MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV85MCA8LSBwYXJtc18zX21ldGEKcGFybXNfM19tZXRhXzkwJG9tZWdhIDwtIDEvOTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfOTAgPC0gc3NhKAogIHgwID0geDBfM19tZXRhLAogIGEgPSBhXzNfbWV0YSwKICBudSA9IG51XzNfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzNfbWV0YV85MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfOTAgPC0gb3V0XzNfbWV0YV85MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfM19tZXRhXzkwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV85MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV85MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfbWV0YV85MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzkwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzkwIDwtIHNzYSgKICAgIHgwID0geDBfM19tZXRhLAogICAgYSA9IGFfM19tZXRhLAogICAgbnUgPSBudV8zX21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzNfbWV0YV85MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV85MCA8LSBvdXRfMTAwXzNfbWV0YV85MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX21ldGFfOTBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfOTAKfQoKc2ltX291dHB1dF8zX21ldGFfOTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfbWV0YV85MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfOTAgPC0gc2ltX291dHB1dF8zX21ldGFfOTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfbWV0YV85MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV85MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV85MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzkwKQpzaW1fc3VtbWFyeV8zX21ldGFfOTAKYGBgCgoKCgoKCgojIyMjIDE4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xODAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xODAkb21lZ2EgPC0gMS8xODAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDIwKQpvdXRfM19tZXRhXzE4MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzE4MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTgwIDwtIG91dF8zX21ldGFfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTgwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xODAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzE4MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzE4MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xODAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzE4MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xODAgPC0gb3V0XzEwMF8zX21ldGFfMTgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xODBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTgwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzE4MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzE4MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTgwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzE4MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzE4MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xODAgPC0gc2ltX291dHB1dF8zX21ldGFfMTgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTgwKQpzaW1fc3VtbWFyeV8zX21ldGFfMTgwCmBgYAoKIyMjIyAxMTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMTEwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMTEwJG9tZWdhIDwtIDEvMTEwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzExMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzExMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTEwIDwtIG91dF8zX21ldGFfMTEwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xMTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMTEwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzExMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzExMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xMTAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzExMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xMTAgPC0gb3V0XzEwMF8zX21ldGFfMTEwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xMTBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTEwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzExMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzExMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTEwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzExMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzExMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xMTAgPC0gc2ltX291dHB1dF8zX21ldGFfMTEwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTEwKQpzaW1fc3VtbWFyeV8zX21ldGFfMTEwCmBgYAoKIyMjIyAxMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMTIwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMTIwJG9tZWdhIDwtIDEvMTIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzEyMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzEyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTIwIDwtIG91dF8zX21ldGFfMTIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMTIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzEyMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzEyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xMjAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzEyMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xMjAgPC0gb3V0XzEwMF8zX21ldGFfMTIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xMjBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTIwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzEyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzEyMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTIwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzEyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzEyMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMTIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTIwKQpzaW1fc3VtbWFyeV8zX21ldGFfMTIwCmBgYAoKIyMjIyAxMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMTMwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMTMwJG9tZWdhIDwtIDEvMTMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzEzMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzEzMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMTMwIDwtIG91dF8zX21ldGFfMTMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMTMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8xMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMTMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzEzMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzEzMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8xMzAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzEzMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8xMzAgPC0gb3V0XzEwMF8zX21ldGFfMTMwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8xMzBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMTMwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzEzMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzEzMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMTMwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzEzMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzEzMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8xMzAgPC0gc2ltX291dHB1dF8zX21ldGFfMTMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTMwKQpzaW1fc3VtbWFyeV8zX21ldGFfMTMwCmBgYAoKCgoKCgoKCgoKCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzNfbWV0YV8xNTAgPC0gcGFybXNfM19tZXRhCnBhcm1zXzNfbWV0YV8xNTAkb21lZ2EgPC0gMS8xNTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8zX21ldGFfMTUwIDwtIHNzYSgKICB4MCA9IHgwXzNfbWV0YSwKICBhID0gYV8zX21ldGEsCiAgbnUgPSBudV8zX21ldGEsCiAgcGFybXMgPSBwYXJtc18zX21ldGFfMTUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzNfbWV0YV8xNTAgPC0gb3V0XzNfbWV0YV8xNTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzNfbWV0YV8xNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfM19tZXRhXzE1MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzNfbWV0YV8xNTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX21ldGFfMTUwIDwtIGxpc3QoKQpzaW1fbGlzdF8zX21ldGFfMTUwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfM19tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzNfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfM19tZXRhXzE1MCA8LSBzc2EoCiAgICB4MCA9IHgwXzNfbWV0YSwKICAgIGEgPSBhXzNfbWV0YSwKICAgIG51ID0gbnVfM19tZXRhLAogICAgcGFybXMgPSBwYXJtc18zX21ldGFfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19tZXRhXzE1MCA8LSBvdXRfMTAwXzNfbWV0YV8xNTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfM19tZXRhXzE1MFtbaV1dIDwtIHNpbV9kYXRhXzNfbWV0YV8xNTAKfQoKc2ltX291dHB1dF8zX21ldGFfMTUwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zX21ldGFfMTUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfbWV0YV8xNTAgPC0gc2ltX291dHB1dF8zX21ldGFfMTUwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zX21ldGFfMTUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19tZXRhXzE1MCA8LSBzaW1fb3V0cHV0XzNfbWV0YV8xNTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5XzNfbWV0YV8xNTAKYGBgCgoKIyMjIyAyMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMjIwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMjIwJG9tZWdhIDwtIDEvMjIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzIyMCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzIyMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMjIwIDwtIG91dF8zX21ldGFfMjIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMjIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8yMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMjIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzIyMCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzIyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8yMjAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzIyMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8yMjAgPC0gb3V0XzEwMF8zX21ldGFfMjIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8yMjBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMjIwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzIyMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzIyMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMjIwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzIyMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzIyMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8yMjAgPC0gc2ltX291dHB1dF8zX21ldGFfMjIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjIwKQpzaW1fc3VtbWFyeV8zX21ldGFfMjIwCmBgYAoKCgoKIyMjIyAyNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMjcwIDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMjcwJG9tZWdhIDwtIDEvMjcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzI3MCA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzI3MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMjcwIDwtIG91dF8zX21ldGFfMjcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMjcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8yNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMjcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzI3MCA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzI3MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8yNzAgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzI3MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8yNzAgPC0gb3V0XzEwMF8zX21ldGFfMjcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8yNzBbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMjcwCn0KCnNpbV9vdXRwdXRfM19tZXRhXzI3MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzI3MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMjcwIDwtIHNpbV9vdXRwdXRfM19tZXRhXzI3MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzI3MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8yNzAgPC0gc2ltX291dHB1dF8zX21ldGFfMjcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjcwKQpzaW1fc3VtbWFyeV8zX21ldGFfMjcwCmBgYAoKIyMjIyAzNjUgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zX21ldGFfMzY1IDwtIHBhcm1zXzNfbWV0YQpwYXJtc18zX21ldGFfMzY1JG9tZWdhIDwtIDEvMzY1CgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfM19tZXRhXzM2NSA8LSBzc2EoCiAgeDAgPSB4MF8zX21ldGEsCiAgYSA9IGFfM19tZXRhLAogIG51ID0gbnVfM19tZXRhLAogIHBhcm1zID0gcGFybXNfM19tZXRhXzM2NSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8zX21ldGFfMzY1IDwtIG91dF8zX21ldGFfMzY1JGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8zX21ldGFfMzY1IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzNfbWV0YV8zNjUsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8zX21ldGFfMzY1CmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19tZXRhXzM2NSA8LSBsaXN0KCkKc2ltX2xpc3RfM19tZXRhXzM2NSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzLCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzNfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8zX21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzNfbWV0YV8zNjUgPC0gc3NhKAogICAgeDAgPSB4MF8zX21ldGEsCiAgICBhID0gYV8zX21ldGEsCiAgICBudSA9IG51XzNfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfM19tZXRhXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzNfbWV0YV8zNjUgPC0gb3V0XzEwMF8zX21ldGFfMzY1JGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfbWV0YV8zNjVbW2ldXSA8LSBzaW1fZGF0YV8zX21ldGFfMzY1Cn0KCnNpbV9vdXRwdXRfM19tZXRhXzM2NSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19tZXRhXzM2NSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX21ldGFfMzY1IDwtIHNpbV9vdXRwdXRfM19tZXRhXzM2NSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19tZXRhXzM2NQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfbWV0YV8zNjUgPC0gc2ltX291dHB1dF8zX21ldGFfMzY1ICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzY1KQpzaW1fc3VtbWFyeV8zX21ldGFfMzY1CmBgYAoKCgoKIyMjIyBSZXN1bHRzCmBgYHtyfQp3YW5pbmdfcmVzdWx0c18zIDwtIHNpbV9zdW1tYXJ5XzNfbWV0YSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzMpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfNykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8yMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8zMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV80MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV81MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV82MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV83MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV84MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV85MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xODApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMTEwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzEyMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8xMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMTUwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfM19tZXRhXzIyMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfbWV0YV8yNzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX21ldGFfMzY1KSAlPiUKICBtdXRhdGUoaW1tdW5pdHlfZHVyYXRpb24gPSAxL29tZWdhKSAlPiUKICBhcnJhbmdlKGltbXVuaXR5X2R1cmF0aW9uKSAlPiUKICBtdXRhdGUobW9kZWwgPSAibWV0YSIsCiAgICAgICAgIHBhdGNoZXMgPSAzKQoKd3JpdGVfY3N2KHdhbmluZ19yZXN1bHRzXzMsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfMy5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfMwoKYGBgCgpgYGB7cn0KZ2dwbG90KHdhbmluZ19yZXN1bHRzXzMsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgoKCgoKCiMjIDE0IE1ldGFwb3B1bGF0aW9uIE1vZGVsIAoKVGhlIHNhbWUgbWV0YXBvcHVsYXRpb24gU0VJUlMgbW9kZWwgd2FzIHRoZW4gdXNlZCB0byBtb2RlbCB0aGUgZHluYW1pY3Mgb2YgcGVyc2lzdGVuY2UgaW4gYSAxNC1wYXRjaCBzeXN0ZW0gYW5kIHVuZGVyc3RhbmQgdGhlIGVmZmVjdCBvZiB3YW5pbmcgaW1tdW5pdHkuCgoKIyMjU2V0LXVwCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKcGF0Y2hQb3BTaXplXzE0IDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgUGF0Y2ggc2l6ZQpVIDwtIGxlbmd0aChwYXRjaFBvcFNpemVfMTQpICAgICAgICAgICAgICAgICAgICAjIE51bWJlciBvZiBwYXRjaGVzCmluaXRpYWxfaW5mZWN0ZWQgPC0gIGFzLnZlY3RvcihybXVsdGlub20oMSwgMSwgcmVwKDAuNSwgVSkpKSAgICMgSW5pdGlhbCBpbmZlY3RlZCAoaW5pdGlhbCBpbmZlY3RlZCBwYXRjaCByYW5kb21seSBnZW5lcmF0ZWQpCmluaXRpYWxfaW5mZWN0ZWRfcGF0Y2ggPC0gd2hpY2goaW5pdGlhbF9pbmZlY3RlZCA+IDApCnNpbU5hbWUgPC0gIlNJUlMgbWV0YXBvcHVsYXRpb24gbW9kZWwiICAgICAgICMgU2ltdWxhdGlvbiBuYW1lCnRmIDwtIDM2NSozICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEZpbmFsIHRpbWUKCiMgQWd0YSBIdW50ZXItR2F0aGVyZXIgY29udGFjdCByYXRlcwp3aXRoaW5fcG9wX2NvbnRhY3QgPSAxCmJldHdlZW5fcG9wX2NvbnRhY3QgPSAwLjUvVSAgICAgIyBub3JtYWxpc2VkIGJ5IG51bWJlciBvZiBwYXRjaGVzIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwXzE0X21ldGEgPC0gdW5saXN0KGxhcHBseSgKICBzZXFfbGVuKFUpLCAKICBmdW5jdGlvbihpKXsgCiAgICBjKHBhdGNoUG9wU2l6ZV8xNFtpXSAtIGluaXRpYWxfaW5mZWN0ZWRbaV0sIGluaXRpYWxfaW5mZWN0ZWRbaV0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8xNFtpXSkKICB9CikpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKGkpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIGkpKSkKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnVfMTRfbWV0YSA8LSBtYXRyaXgoYyggLTEsICAwLCAgMCwgKzEsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsICMgUwogICAgICAgICAgICAgICAgICAgICArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICAwLCAgMCwgIyBFCiAgICAgICAgICAgICAgICAgICAgICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsIC0xLCAjIEkKICAgICAgICAgICAgICAgICAgICAgIDAsICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICMgUiAKICAgICAgICAgICAgICAgICAgICAgIDAsICAwLCAgMCwgIDAsICsxLCAtMSAsLTEsIC0xLCAtMSwgLTEpLCAjIE4KICAgICAgICAgICAgIG5yb3c9NSxieXJvdz1UUlVFKQoKIyBEZWZpbmUgcHJvcGVuc2l0eSBmdW5jdGlvbnMKIyBNYXNzLWFjdGlvbgphXzE0X21ldGEgPC0KICB1bmxpc3QobGFwcGx5KAogICAgc2VxX2xlbihVKSwKICAgIGZ1bmN0aW9uKHBhdGNoKSB7CiAgICAgIGkgPC0gcGF0Y2gKICAgICAgcGF0Y2hlcyA8LSAxOlUKICAgICAgI2ogPC0gaWYgKHBhdGNoID09IDEpIFUgZWxzZSBwYXRjaCAtIDEKICAgICAgb3RoZXJfcGF0Y2hlcyA8LSBwYXRjaGVzWy1pXQogICAgICBwYXRjaF9iZXRhIDwtIGMoKQogICAgICBmb3IoayBpbiAoMTooVS0xKSkpewogICAgICAgIHBhdGNoX2JldGFba10gPSBwYXN0ZTAoIisoYmV0YV8iLCBvdGhlcl9wYXRjaGVzW2tdLGksICIqSSIsIG90aGVyX3BhdGNoZXNba10sICIvTiIsIG90aGVyX3BhdGNoZXNba10sICIpKlMiLCBpKQogICAgICB9CiAgICAgIGMoCiAgICAgICAgcGFzdGUwKCIoYmV0YV8iLCBpLCBpLCAiKkkiLCBpLCIvTiIsIGksICIpKlMiLGksIHBhc3RlMChwYXRjaF9iZXRhLCBjb2xsYXBzZT0iIikpLCAjIEluZmVjdGlvbgogICAgICAgIHBhc3RlMCgic2lnbWEqRSIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmVjb21lcyBpbmZlY2lvdXMKICAgICAgICBwYXN0ZTAoImdhbW1hKkkiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlY292ZXJ5IGZyb20gaW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJvbWVnYSpSIiwgaSksICAgICAgICMgTG9zcyBvZiBpbW11bml0eQogICAgICAgIHBhc3RlMCgibXUqTiIsIGkpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aHMKICAgICAgICBwYXN0ZTAoIm11KlMiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUykKICAgICAgICBwYXN0ZTAoIm11KkUiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoRSkKICAgICAgICBwYXN0ZTAoIm11KkkiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoSSkKICAgICAgICBwYXN0ZTAoIm11KlIiLCBpKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUikKICAgICAgICBwYXN0ZTAoImFscGhhKkkiLCBpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyBmcm9tIGluZmVjdGlvbgogICAgICAgIAogICAgICApCiAgICB9CiAgKSkKCmBgYAoKCgojIyMgUnVuIE1ldGFwb3B1bGF0aW9uIE1vZGVsCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGEgPC0gbGlzdCgKICBzaWdtYSA9IDAuMTc1LCAgICAgICAgICAgICAgICAgICAgICAgICAgIyBFIHRvIEkgcmF0ZQogIGdhbW1hID0gMC4yLCAgICAgICAgICAgICAgICAgICAgICAgICAgICMgSSB0byBSIHJhdGUKICBvbWVnYSA9IDEvMTAwLCAgICAgICAgICAgICAgICAgICAgICAgICAjIFIgdG8gUyByYXRlCiAgbXUgPSBkZW1vX3N1bSRCaXJ0aF9yYXRlX2RhaWx5X01lYW4sICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGgvZGVhdGggcmF0ZSBwZXIgcGVyc29uIHBlciBkYXkKICBhbHBoYSA9IDEvMTAwMCkgCgojIERlZmluZSB0cmFuc21pc3Npb24gdGVybXMgYW5kIHBvcHVsYXRlIG5leHQtZ2VuZXJhdGlvbiBtYXRyaXgKYmV0YSA8LSAwLjYKCm5leHRnZW5fMTRfbWF0cml4IDwtIG1hdHJpeChucm93ID0gVSwgbmNvbCA9IFUsIGRhdGEgPSAwKQpiZXRhXzE0X21hdHJpeCA8LSBtYXRyaXgobnJvdyA9IFUsIG5jb2wgPSBVLCBkYXRhID0gMCkKCgpmb3IoaSBpbiAxOlUpewogIGZvcihqIGluIDE6VSl7CiAgICBwYXJtc18xNF9tZXRhW1twYXN0ZTAoImJldGFfIixpLGkpXV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgbmV4dGdlbl8xNF9tYXRyaXhbaSxpXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhKigxL3Bhcm1zXzE0X21ldGEkZ2FtbWEpCiAgICBwYXJtc18xNF9tZXRhW1twYXN0ZTAoImJldGFfIixqLGkpXV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEKICAgIG5leHRnZW5fMTRfbWF0cml4W2osaV0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfMTRfbWV0YSRnYW1tYSkKICAgIG5leHRnZW5fMTRfbWF0cml4W2ksal0gPSBiZXR3ZWVuX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfMTRfbWV0YSRnYW1tYSkKICAgIHBhcm1zXzE0X21ldGFbW3Bhc3RlMCgiYmV0YV8iLGosaildXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgICBuZXh0Z2VuXzE0X21hdHJpeFtqLGpdID0gd2l0aGluX3BvcF9jb250YWN0KmJldGEqKDEvcGFybXNfMTRfbWV0YSRnYW1tYSkKICAgIGJldGFfMTRfbWF0cml4W2ksaV0gPSB3aXRoaW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8xNF9tYXRyaXhbaixpXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8xNF9tYXRyaXhbaSxqXSA9IGJldHdlZW5fcG9wX2NvbnRhY3QqYmV0YQogICAgYmV0YV8xNF9tYXRyaXhbaixqXSA9IHdpdGhpbl9wb3BfY29udGFjdCpiZXRhCiAgfQogIHBhcm1zXzE0X21ldGFbW3Bhc3RlMCgiTiIsIGkpXV0gPSBwYXRjaFBvcFNpemVfMTRbaV0KfQpgYGAKCgpgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyNSkKb3V0XzE0X21ldGEgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGEsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBQbG90CnBsb3RfZGF0YV8xNF9tZXRhIDwtIG91dF8xNF9tZXRhJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGEsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZShhbHBoYT0wLjgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIChEYXlzKSIsCiAgICAgICB5PSJOdW1iZXIgb2YgSW5kaXZpZHVhbHMiLAogICAgICAgY29sb3VyPSJTdGF0ZSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhCgpnZ3NhdmUoZmlsZW5hbWUgPSAibWV0YV8xNF9wbG90LnBkZiIsIAogICAgICAgcGxvdCA9IHBsb3RfMTRfbWV0YSwKICAgICAgIGRldmljZSA9ICJwZGYiLAogICAgICAgd2lkdGggPSA3LCAKICAgICAgIGhlaWdodCA9IDgsCiAgICAgICBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvUGxvdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscyIpCmBgYAoKYGBge3J9CiMjIFRhYmxlIHNob3dpbmcgZXh0aW5jdGlvbi90cmFuc21pc3Npb24gaW5mbyBmb3IgZWFjaCBwYXRjaAoKZXh0aW5jdF9kYXRhXzE0X21ldGEgPC0gb3V0XzE0X21ldGEkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHN0YXRlPT0iSSIgJiBjb3VudCA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZT09IkkiICYgY291bnQgPT0gMCB+IEYpKSAlPiUKICBkcm9wX25hKCkgJT4lCiAgc2VsZWN0KHBhdGNoLCBjb3VudCwgcGVyc2lzdCkKZXh0aW5jdF9kYXRhXzE0X21ldGEKYGBgCgoKYGBge3J9CmJldGFfMTRfbWV0YSA8LSBiZXRhLm5nbShiZXRhXzE0X21hdHJpeCkKcGFzdGUwKCJCZXRhIGZvciB3aG9sZSBzeXN0ZW0gPSAiLCBiZXRhXzE0X21ldGEpCgoKUjBfMTRfbWV0YSA8LSBSMG5nbShuZXh0Z2VuXzE0X21hdHJpeCkKcGFzdGUwKCJSMCA9ICIsIFIwXzE0X21ldGEpCgoKcGFzdGUwKCJBY3R1YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCBlbmQgb2Ygc2ltID0gIiwgc3VtKGV4dGluY3RfZGF0YV8xNF9tZXRhJGNvdW50KSkKICMgVG90YWwgbnVtYmVyIG9mIGluZmVjdGVkcyBhdCB0aGUgZW5kIG9mIHNpbSBhY3Jvc3MgYWxsIHBhdGNoZXMKCnNpbV9lbmRwb2ludF8xNF9tZXRhIDwtIGFzX3RpYmJsZShvdXRfMTRfbWV0YSRkYXRhKSAlPiUKICBzbGljZV9tYXgodCkgJT4lCiAgZGlzdGluY3QoKQoKCnBhc3RlMCgiRGlkIHNpbXVsYXRpb24gcnVuIHJlYWNoIGZpbmFsIGVuZHBvaW50PyIpCmlmIChzaW1fZW5kcG9pbnRfMTRfbWV0YSR0ID49IHRmKSB7CiAgcHJpbnQoIlllcyIpCn0gZWxzZSB7CiAgcHJpbnQoIk5vIil9CgpgYGAKCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzE0IDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdChsYXBwbHkoCiAgc2VxX2xlbihVKSwgCiAgZnVuY3Rpb24oeCl7IAogICAgYyhwYXRjaFBvcFNpemVfMTRbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfMTRbeF0pCiAgfQopKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCiAgCiAgb3V0XzEwMF8xNF9tZXRhIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhIDwtIG91dF8xMDBfMTRfbWV0YSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YQp9CgpzaW1fb3V0cHV0XzE0X21ldGEgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGEpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YSA8LSBzaW1fb3V0cHV0XzE0X21ldGEgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGEKYGBgCgoKCmBgYHtyfQojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YSA8LSBzaW1fb3V0cHV0XzE0X21ldGEgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwMCkKc2ltX3N1bW1hcnlfMTRfbWV0YQpgYGAKCiMjIyBWYXJ5aW5nIHdhaW5pbmcgaW1tdW5pdHkgey50YWJzZXQgLnRhYnNldC1mYWRlIC50YWJzZXQtcGlsbHN9CiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMCRvbWVnYSA8LSAwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8wIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8wIDwtIG91dF8xNF9tZXRhXzAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzAgPC0gb3V0XzEwMF8xNF9tZXRhXzAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8wW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8wCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8wIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8wIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8wICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzAKYGBgCgoKIyMjIyAxMCBEYXlzCgpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzEwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8xMCRvbWVnYSA8LSAxLzEwCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzEwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzEwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTAgPC0gb3V0XzE0X21ldGFfMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzEwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzEwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xMCA8LSBvdXRfMTAwXzE0X21ldGFfMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8xMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzEwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzEwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzEwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzEwCmBgYAoKCiMjIyMgMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzIwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8yMCRvbWVnYSA8LSAxLzIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8yMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzIwIDwtIG91dF8xNF9tZXRhXzIwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzIwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzIwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8yMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8yMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMjAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMjAgPC0gb3V0XzEwMF8xNF9tZXRhXzIwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMjBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzIwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8yMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8yMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8yMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8yMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzIwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMjAKYGBgCgoKCgoKCiMjIyMgMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzMwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8zMCRvbWVnYSA8LSAxLzMwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8zMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8zMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzMwIDwtIG91dF8xNF9tZXRhXzMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzMwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8zMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8zMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8zMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMzAgPC0gb3V0XzEwMF8xNF9tZXRhXzMwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMzBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzMwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8zMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8zMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzMwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8zMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8zMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8zMApgYGAKCgoKIyMjIyA0MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfNDAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzQwJG9tZWdhIDwtIDEvNDAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzQwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzQwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfNDAgPC0gb3V0XzE0X21ldGFfNDAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfNDAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV80MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfNDAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzQwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzQwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV80MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzQwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV80MCA8LSBvdXRfMTAwXzE0X21ldGFfNDAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV80MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfNDAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzQwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzQwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfNDAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzQwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzQwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV80MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNDAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS80MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV80MApgYGAKCgoKCgoKCiMjIyMgNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzUwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV81MCRvbWVnYSA8LSAxLzUwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV81MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV81MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzUwIDwtIG91dF8xNF9tZXRhXzUwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzUwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfNTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzUwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV81MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV81MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfNTAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV81MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfNTAgPC0gb3V0XzEwMF8xNF9tZXRhXzUwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfNTBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzUwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV81MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV81MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzUwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV81MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV81MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfNTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzUwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5XzE0X21ldGFfNTAKYGBgCgoKCgoKIyMjIyA2MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfNjAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzYwJG9tZWdhIDwtIDEvNjAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzYwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzYwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfNjAgPC0gb3V0XzE0X21ldGFfNjAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfNjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV82MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfNjAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzYwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzYwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV82MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV82MCA8LSBvdXRfMTAwXzE0X21ldGFfNjAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV82MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfNjAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzYwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzYwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfNjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzYwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzYwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV82MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfNjAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS82MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV82MApgYGAKCgoKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzcwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV83MCRvbWVnYSA8LSAxLzcwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV83MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV83MCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzcwIDwtIG91dF8xNF9tZXRhXzcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzcwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfNzAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV83MCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV83MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfNzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV83MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfNzAgPC0gb3V0XzEwMF8xNF9tZXRhXzcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfNzBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzcwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV83MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV83MCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzcwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV83MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV83MAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfNzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNzApCnNpbV9zdW1tYXJ5XzE0X21ldGFfNzAKYGBgCgoKIyMjIyA4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfODAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzgwJG9tZWdhIDwtIDEvODAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzgwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzgwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfODAgPC0gb3V0XzE0X21ldGFfODAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfODAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV84MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfODAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzgwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV84MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV84MCA8LSBvdXRfMTAwXzE0X21ldGFfODAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV84MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfODAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzgwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzgwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfODAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzgwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzgwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV84MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfODAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS84MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV84MApgYGAKCgoKIyMjIyA5MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfOTAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzkwJG9tZWdhIDwtIDEvOTAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzkwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzkwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfOTAgPC0gb3V0XzE0X21ldGFfOTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfOTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV85MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfOTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzkwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzkwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV85MCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzkwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV85MCA8LSBvdXRfMTAwXzE0X21ldGFfOTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV85MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfOTAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzkwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzkwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfOTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzkwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzkwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV85MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfOTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS85MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV85MApgYGAKCgoKCgoKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8xODAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjApCm91dF8xNF9tZXRhXzE4MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xODAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8xODAgPC0gb3V0XzE0X21ldGFfMTgwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzE4MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzE4MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTgwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8xODAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMTgwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xODAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xODAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzE4MCA8LSBvdXRfMTAwXzE0X21ldGFfMTgwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMTgwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8xODAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzE4MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8xODApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8xODAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzE4MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8xODAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzE4MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTgwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTgwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzE4MApgYGAKCiMjIyMgMTEwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8xMTAgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzExMCRvbWVnYSA8LSAxLzExMAoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMTEwIDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzExMCwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzExMCA8LSBvdXRfMTRfbWV0YV8xMTAkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMTEwIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMTEwLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8xMTAKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzExMCA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8xMTAgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzExMCA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzExMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMTEwIDwtIG91dF8xMDBfMTRfbWV0YV8xMTAkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8xMTBbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzExMAp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMTEwIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzExMCkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzExMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTEwICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzExMAoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMTEwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMTAgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMTApCnNpbV9zdW1tYXJ5XzE0X21ldGFfMTEwCmBgYAoKIyMjIyAxMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzEyMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMTIwJG9tZWdhIDwtIDEvMTIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8xMjAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTIwIDwtIG91dF8xNF9tZXRhXzEyMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8xMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzEyMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMTIwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzEyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMTIwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xMjAgPC0gb3V0XzEwMF8xNF9tZXRhXzEyMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzEyMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTIwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8xMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMTIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMTIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEyMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEyMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8xMjAKYGBgCgojIyMjIDEzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMTMwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8xMzAkb21lZ2EgPC0gMS8xMzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzEzMCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8xMzAgPC0gb3V0XzE0X21ldGFfMTMwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzEzMCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzEzMCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMTMwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8xMzAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMTMwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8xMzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8xMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzEzMCA8LSBvdXRfMTAwXzE0X21ldGFfMTMwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMTMwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8xMzAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzEzMCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8xMzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8xMzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzEzMCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8xMzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzEzMCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMTMwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTMwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzEzMApgYGAKCgoKCgoKCgoKCgoKIyMjIyAxNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzE1MCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMTUwJG9tZWdhIDwtIDEvMTUwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8xNTAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTUwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMTUwIDwtIG91dF8xNF9tZXRhXzE1MCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8xNTAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8xNTAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzE1MApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMTUwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzE1MCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMTUwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8xNTAgPC0gb3V0XzEwMF8xNF9tZXRhXzE1MCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzE1MFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMTUwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8xNTAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMTUwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMTUwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8xNTAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMTUwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8xNTAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzE1MCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8xNTAKYGBgCgoKIyMjIyAyMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNF9tZXRhXzIyMCA8LSBwYXJtc18xNF9tZXRhCnBhcm1zXzE0X21ldGFfMjIwJG9tZWdhIDwtIDEvMjIwCgoKIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCg0KQpvdXRfMTRfbWV0YV8yMjAgPC0gc3NhKAogIHgwID0geDBfMTRfbWV0YSwKICBhID0gYV8xNF9tZXRhLAogIG51ID0gbnVfMTRfbWV0YSwKICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMjIwLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhXzE0X21ldGFfMjIwIDwtIG91dF8xNF9tZXRhXzIyMCRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnBsb3RfMTRfbWV0YV8yMjAgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfMTRfbWV0YV8yMjAsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmZhY3RvcihwYXRjaCwgbGV2ZWxzID0gdW5pcXVlKHBhdGNoKSkgLG5jb2wgPSAzLCBzY2FsZXMgPSAiZnJlZV95IikrCiAgbGFicyh4PSJUaW1lIiwKICAgICAgIHk9IkZyZXF1ZW5jeSIpKwogIHRoZW1lX2J3KCkKcGxvdF8xNF9tZXRhXzIyMApgYGAKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE0X21ldGFfMjIwIDwtIGxpc3QoKQpzaW1fbGlzdF8xNF9tZXRhXzIyMCA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIHBhdGNoUG9wU2l6ZV8zIDwtICAgICBzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCwgcmVwbGFjZSA9IFRSVUUpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICB4MF8xNF9tZXRhIDwtIHVubGlzdCgKICAgICAgbGFwcGx5KAogICAgICAgIHNlcV9sZW4oVSksCiAgICAgICAgZnVuY3Rpb24oeCl7CiAgICAgICAgICBjKHBhdGNoUG9wU2l6ZV8zW3hdIC0gaW5pdGlhbF9pbmZlY3RlZFt4XSwgaW5pdGlhbF9pbmZlY3RlZFt4XSwgMCwgMCwgcGF0Y2hQb3BTaXplXzNbeF0pCiAgICAgICAgICB9CiAgICAgICAgKSkKCm5hbWVzKHgwXzE0X21ldGEpIDwtIHVubGlzdChsYXBwbHkoc2VxX2xlbihVKSwgZnVuY3Rpb24oeCkgcGFzdGUwKGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKSwgeCkpKQoKICBvdXRfMTAwXzE0X21ldGFfMjIwIDwtIHNzYSgKICAgIHgwID0geDBfMTRfbWV0YSwKICAgIGEgPSBhXzE0X21ldGEsCiAgICBudSA9IG51XzE0X21ldGEsCiAgICBwYXJtcyA9IHBhcm1zXzE0X21ldGFfMjIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTRfbWV0YV8yMjAgPC0gb3V0XzEwMF8xNF9tZXRhXzIyMCRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgICAgaW50byA9IGMoInN0YXRlIiwgInBhdGNoIiksIAogICAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBwYXRjaCwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNF9tZXRhXzIyMFtbaV1dIDwtIHNpbV9kYXRhXzE0X21ldGFfMjIwCn0KCnNpbV9vdXRwdXRfMTRfbWV0YV8yMjAgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE0X21ldGFfMjIwKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE0X21ldGFfMjIwIDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8yMjAgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE0X21ldGFfMjIwCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTRfbWV0YV8yMjAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzIyMCAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIyMCkKc2ltX3N1bW1hcnlfMTRfbWV0YV8yMjAKYGBgCgoKCgojIyMjIDI3MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE0X21ldGFfMjcwIDwtIHBhcm1zXzE0X21ldGEKcGFybXNfMTRfbWV0YV8yNzAkb21lZ2EgPC0gMS8yNzAKCgojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDQpCm91dF8xNF9tZXRhXzI3MCA8LSBzc2EoCiAgeDAgPSB4MF8xNF9tZXRhLAogIGEgPSBhXzE0X21ldGEsCiAgbnUgPSBudV8xNF9tZXRhLAogIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yNzAsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfMTRfbWV0YV8yNzAgPC0gb3V0XzE0X21ldGFfMjcwJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJJRCIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIHNlcGFyYXRlKElELCAKICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgc2VwID0gIig/PD1bQS1aYS16XSkoPz1bMC05XSkiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKcGxvdF8xNF9tZXRhXzI3MCA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV8xNF9tZXRhXzI3MCwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKCkrCiAgZmFjZXRfd3JhcCh+ZmFjdG9yKHBhdGNoLCBsZXZlbHMgPSB1bmlxdWUocGF0Y2gpKSAsbmNvbCA9IDMsIHNjYWxlcyA9ICJmcmVlX3kiKSsKICBsYWJzKHg9IlRpbWUiLAogICAgICAgeT0iRnJlcXVlbmN5IikrCiAgdGhlbWVfYncoKQpwbG90XzE0X21ldGFfMjcwCmBgYApgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTRfbWV0YV8yNzAgPC0gbGlzdCgpCnNpbV9saXN0XzE0X21ldGFfMjcwIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgcGF0Y2hQb3BTaXplXzMgPC0gICAgIHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0LCByZXBsYWNlID0gVFJVRSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIHgwXzE0X21ldGEgPC0gdW5saXN0KAogICAgICBsYXBwbHkoCiAgICAgICAgc2VxX2xlbihVKSwKICAgICAgICBmdW5jdGlvbih4KXsKICAgICAgICAgIGMocGF0Y2hQb3BTaXplXzNbeF0gLSBpbml0aWFsX2luZmVjdGVkW3hdLCBpbml0aWFsX2luZmVjdGVkW3hdLCAwLCAwLCBwYXRjaFBvcFNpemVfM1t4XSkKICAgICAgICAgIH0KICAgICAgICApKQoKbmFtZXMoeDBfMTRfbWV0YSkgPC0gdW5saXN0KGxhcHBseShzZXFfbGVuKFUpLCBmdW5jdGlvbih4KSBwYXN0ZTAoYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpLCB4KSkpCgogIG91dF8xMDBfMTRfbWV0YV8yNzAgPC0gc3NhKAogICAgeDAgPSB4MF8xNF9tZXRhLAogICAgYSA9IGFfMTRfbWV0YSwKICAgIG51ID0gbnVfMTRfbWV0YSwKICAgIHBhcm1zID0gcGFybXNfMTRfbWV0YV8yNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNF9tZXRhXzI3MCA8LSBvdXRfMTAwXzE0X21ldGFfMjcwJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBzZXBhcmF0ZShJRCwgCiAgICAgICAgICAgICBpbnRvID0gYygic3RhdGUiLCAicGF0Y2giKSwgCiAgICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIHBhdGNoLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE0X21ldGFfMjcwW1tpXV0gPC0gc2ltX2RhdGFfMTRfbWV0YV8yNzAKfQoKc2ltX291dHB1dF8xNF9tZXRhXzI3MCA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTRfbWV0YV8yNzApCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTRfbWV0YV8yNzAgPC0gc2ltX291dHB1dF8xNF9tZXRhXzI3MCAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTRfbWV0YV8yNzAKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNF9tZXRhXzI3MCA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMjcwICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMjcwKQpzaW1fc3VtbWFyeV8xNF9tZXRhXzI3MApgYGAKCiMjIyMgMzY1IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTRfbWV0YV8zNjUgPC0gcGFybXNfMTRfbWV0YQpwYXJtc18xNF9tZXRhXzM2NSRvbWVnYSA8LSAxLzM2NQoKCiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoNCkKb3V0XzE0X21ldGFfMzY1IDwtIHNzYSgKICB4MCA9IHgwXzE0X21ldGEsCiAgYSA9IGFfMTRfbWV0YSwKICBudSA9IG51XzE0X21ldGEsCiAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzM2NSwKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKQoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV8xNF9tZXRhXzM2NSA8LSBvdXRfMTRfbWV0YV8zNjUkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gIklEIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgc2VwYXJhdGUoSUQsIAogICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICBzZXAgPSAiKD88PVtBLVphLXpdKSg/PVswLTldKSIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpwbG90XzE0X21ldGFfMzY1IDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhXzE0X21ldGFfMzY1LCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoKSsKICBmYWNldF93cmFwKH5mYWN0b3IocGF0Y2gsIGxldmVscyA9IHVuaXF1ZShwYXRjaCkpICxuY29sID0gMywgc2NhbGVzID0gImZyZWVfeSIpKwogIGxhYnMoeD0iVGltZSIsCiAgICAgICB5PSJGcmVxdWVuY3kiKSsKICB0aGVtZV9idygpCnBsb3RfMTRfbWV0YV8zNjUKYGBgCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNF9tZXRhXzM2NSA8LSBsaXN0KCkKc2ltX2xpc3RfMTRfbWV0YV8zNjUgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBwYXRjaFBvcFNpemVfMyA8LSAgICAgc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQsIHJlcGxhY2UgPSBUUlVFKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgeDBfMTRfbWV0YSA8LSB1bmxpc3QoCiAgICAgIGxhcHBseSgKICAgICAgICBzZXFfbGVuKFUpLAogICAgICAgIGZ1bmN0aW9uKHgpewogICAgICAgICAgYyhwYXRjaFBvcFNpemVfM1t4XSAtIGluaXRpYWxfaW5mZWN0ZWRbeF0sIGluaXRpYWxfaW5mZWN0ZWRbeF0sIDAsIDAsIHBhdGNoUG9wU2l6ZV8zW3hdKQogICAgICAgICAgfQogICAgICAgICkpCgpuYW1lcyh4MF8xNF9tZXRhKSA8LSB1bmxpc3QobGFwcGx5KHNlcV9sZW4oVSksIGZ1bmN0aW9uKHgpIHBhc3RlMChjKCJTIiwiRSIsIkkiLCAiUiIsICJOIiksIHgpKSkKCiAgb3V0XzEwMF8xNF9tZXRhXzM2NSA8LSBzc2EoCiAgICB4MCA9IHgwXzE0X21ldGEsCiAgICBhID0gYV8xNF9tZXRhLAogICAgbnUgPSBudV8xNF9tZXRhLAogICAgcGFybXMgPSBwYXJtc18xNF9tZXRhXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE0X21ldGFfMzY1IDwtIG91dF8xMDBfMTRfbWV0YV8zNjUkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAiSUQiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHNlcGFyYXRlKElELCAKICAgICAgICAgICAgIGludG8gPSBjKCJzdGF0ZSIsICJwYXRjaCIpLCAKICAgICAgICAgICAgIHNlcCA9ICIoPzw9W0EtWmEtel0pKD89WzAtOV0pIikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgcGF0Y2gsIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTRfbWV0YV8zNjVbW2ldXSA8LSBzaW1fZGF0YV8xNF9tZXRhXzM2NQp9CgpzaW1fb3V0cHV0XzE0X21ldGFfMzY1IDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNF9tZXRhXzM2NSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNF9tZXRhXzM2NSA8LSBzaW1fb3V0cHV0XzE0X21ldGFfMzY1ICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNF9tZXRhXzM2NQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE0X21ldGFfMzY1IDwtIHNpbV9vdXRwdXRfMTRfbWV0YV8zNjUgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzE0X21ldGFfMzY1CmBgYAoKCgoKCiMjIyMgUmVzdWx0cwpgYGB7cn0Kd2FuaW5nX3Jlc3VsdHNfMTQgPC0gc2ltX3N1bW1hcnlfMTRfbWV0YSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMjApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzMwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV80MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfNTApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzYwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV83MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfODApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzkwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xODApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzExMCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMTIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8xMzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzE1MCkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE0X21ldGFfMjIwKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTRfbWV0YV8yNzApICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xNF9tZXRhXzM2NSkgJT4lCiAgbXV0YXRlKGltbXVuaXR5X2R1cmF0aW9uID0gMS9vbWVnYSkgJT4lCiAgYXJyYW5nZShpbW11bml0eV9kdXJhdGlvbikgJT4lCiAgbXV0YXRlKG1vZGVsID0gIm1ldGEiLAogICAgICAgICBwYXRjaGVzID0gMTQpCgp3cml0ZV9jc3Yod2FuaW5nX3Jlc3VsdHNfMTQsIGZpbGUgPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Jlc3VsdHMvd2FuaW5nX3Jlc3VsdHNfMTQuY3N2IikKCndhbmluZ19yZXN1bHRzXzE0CgpgYGAKCmBgYHtyfQpnZ3Bsb3Qod2FuaW5nX3Jlc3VsdHNfMTQsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgc3VtX3BlcnNpc3QpKSArCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludCgpKwogIHRoZW1lX2J3KCkKYGBgCgoKIyMgQ29tYmluZWQgUmVzdWx0cwoKUmVzdWx0cyBmcm9tIHNpbmFsZSBhbmQgbWV0YXBvcHVsYXRpb24gbW9kZWxzIHdlcmUgY29taW5lZCBpbnRvIG9uZSBkYXRhIGZyYW1lIGFuZCB2aXN1YWxpc2VkLiAKCmBgYHtyfQpjb21iaW5lZF93YW5pbmcgPC0gd2FuaW5nX3Jlc3VsdHMgJT4lCiAgYmluZF9yb3dzKHdhbmluZ19yZXN1bHRzX3NpbmdsZSkgJT4lCiAgYmluZF9yb3dzKHdhbmluZ19yZXN1bHRzXzcpICU+JQogIGJpbmRfcm93cyh3YW5pbmdfcmVzdWx0c18zKSAlPiUKICBiaW5kX3Jvd3Mod2FuaW5nX3Jlc3VsdHNfMTQpCgpoZWFkKGNvbWJpbmVkX3dhbmluZykKCgojd3JpdGVfY3N2KGNvbWJpbmVkX3dhbmluZywgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUmVzdWx0cy9jb21iaW5lZF93YW5pbmdfcmVzdWx0cy5jc3YiKQoKYGBgCgoKYGBge3J9CnBhbCA8LSB3ZXNfcGFsZXR0ZSg0LCBuYW1lID0gIlppc3NvdTEiLCB0eXBlID0gImNvbnRpbnVvdXMiKQoKY29tYmluZWRfcGxvdCA8LSBnZ3Bsb3QoY29tYmluZWRfd2FuaW5nLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0LCBjb2xvdXIgPSBhcy5mYWN0b3IocGF0Y2hlcykpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC43LCBzaXplPTEpKwogIGdlb21fcG9pbnQoYWxwaGE9MC41LCBzaXplPTIpKwogIGdlb21fc2VnbWVudCh4ID0gLUluZiwgeSA9IDUwLCB4ZW5kID0gMTQxLjUsIHllbmQgPSA1MCwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA1LCB5ID0gNTAsIHhlbmQgPSA1LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA0Mi41LCB5ID0gNTAsIHhlbmQgPSA0Mi41LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSA5MS41LCB5ID0gNTAsIHhlbmQgPSA5MS41LCB5ZW5kID0gLUluZiwgbGluZXR5cGUgPSAiZGFzaGVkIiwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9zZWdtZW50KHggPSAxNDEuNSwgeSA9IDUwLCB4ZW5kID0gMTQxLjUsIHllbmQgPSAtSW5mLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBjb2xvdXIgPSAiZ3JleSIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAzNjAsIDUwKSkgKwogIGxhYnMoeCA9ICJEdXJhdGlvbiBvZiBpbW11bml0eSAoZGF5cykiLAogICAgICAgeSA9ICJQcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzICglKSIsIAogICAgICAgY29sb3VyID0gIk5vLiBQYXRjaGVzIikrCiAgc2NhbGVfY29sb3JfZGlzY3JldGUodHlwZSA9IHBhbCwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIxIiwgIjMiLCAiNyIsICIxNCIpKSsKICB0aGVtZV9idygpCgpjb21iaW5lZF9wbG90CgpnZ3NhdmUoZmlsZW5hbWUgPSAiY29tYmluZWRfcGxvdF9wYXRjaGVzLnBkZiIsIHBsb3QgPSBjb21iaW5lZF9wbG90LCBkZXZpY2UgPSAicGRmIiwgd2lkdGggPSA3LCBoZWlnaHQgPSA1LCBwYXRoID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy9QbG90cyIpCmBgYAoKYGBge3J9CmdncGxvdChjb21iaW5lZF93YW5pbmcsIGFlcyhpbW11bml0eV9kdXJhdGlvbiwgbWVhbl9wZXJjZW50X2luZmVjdGVkLCBjb2xvdXIgPSBhcy5mYWN0b3IocGF0Y2hlcykpKSsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkgKwogIGxhYnMoeCA9ICJEdXJhdGlvbiBvZiBpbW11bml0eSIsCiAgICAgICB5ID0gIlByb3BvcnRpb24gaW5mZWN0ZWQgYXQgZW5kcG9pbnQgKCUpIiwgCiAgICAgICBjb2xvdXIgPSAiUGF0Y2hlcyIpKwogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKHR5cGUgPSBwYWwsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiMSIsICIzIiwgIjciLCAiMTQiKSkrCiAgdGhlbWVfYncoKQpgYGAKCgojIyAzLVBhdGNoIFNpbmdsZSBQb3B1bGF0aW9uCgojIyMgTW9kZWwgU2V0LXVwCgpNb2RlbCB3YXMgc2V0IHVwIHdpdGggYSBzaW5nbGUgcmFuZG9tbHkgc2VsZWN0ZWQgY2FtcCBzaXplIHdpdGggYSBzaW5nbGUgaW5mZWN0ZWQgaW5kaXZpZHVhbCBhbmQgcGFyYW1ldGVycyBmb3IgcGF0aG9nZW4gWC4gCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKTl9hIDwtICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBQb3B1bGF0aW9uIHNpemUKaW5pdGlhbF9pbmZlY3RlZCA8LSAgMSAgICAjIEluaXRpYWwgaW5mZWN0ZWQKc2ltTmFtZSA8LSAiU0VJUlMgbW9kZWwiICAgICAgICMgU2ltdWxhdGlvbiBuYW1lCnRmIDwtIDM2NSozCgojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zIDwtIGxpc3QoCiAgYmV0YSA9IDAuNiwKICBzaWdtYSA9IDAuMTc1LCAgICAgICAgICAgICAgICAgICAgICAgICAgIyBFIHRvIEkgcmF0ZQogIGdhbW1hID0gMC4yLCAgICAgICAgICAgICAgICAgICAgICAgICAgICMgSSB0byBSIHJhdGUKICBvbWVnYSA9IDEvMTAwLCAgICAgICAgICAgICAgICAgICAgICAgICAjIFIgdG8gUyByYXRlCiAgbXUgPSBkZW1vX3N1bSRCaXJ0aF9yYXRlX2RhaWx5X01lYW4sICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGgvZGVhdGggcmF0ZSBwZXIgcGVyc29uIHBlciBkYXkKICBhbHBoYSA9IDEvMTAwMCkgCgojQ3JlYXRlIHRoZSBuYW1lZCBpbml0aWFsIHN0YXRlIHZlY3RvciBmb3IgdGhlIFUtcGF0Y2ggc3lzdGVtLgoKeDBfYSA8LSBjKE5fYSAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYSkKCm5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiMgRGVmaW5lIHRoZSBzdGF0ZSBjaGFuZ2UgbWF0cml4IGZvciBhIHNpbmdsZSBwYXRjaApudSA8LSBtYXRyaXgoYyggLTEsICAwLCAgMCwgKzEsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsICMgUwogICAgICAgICAgICAgICAgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAgMCwgIDAsICMgRQogICAgICAgICAgICAgICAgMCwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAtMSwgIyBJCiAgICAgICAgICAgICAgICAwLCAgMCwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgLTEsICAwLCAjIFIgCiAgICAgICAgICAgICAgICAwLCAgMCwgIDAsICAwLCArMSwgLTEgLC0xLCAtMSwgLTEsIC0xKSwgIyBOCiAgICAgICAgICAgICBucm93PTUsYnlyb3c9VFJVRSkKCiMgRGVmaW5lIHByb3BlbnNpdHkgZnVuY3Rpb25zCmEgPC1jKAogICAgICAgIHBhc3RlMCgiKGJldGEqSS9OKSpTIiksICMgSW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJzaWdtYSpFIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCZWNvbWVzIGluZmVjaW91cwogICAgICAgIHBhc3RlMCgiZ2FtbWEqSSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgUmVjb3ZlcnkgZnJvbSBpbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoIm9tZWdhKlIiKSwgICAgICAgIyBMb3NzIG9mIGltbXVuaXR5CiAgICAgICAgcGFzdGUwKCJtdSpOIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRocwogICAgICAgIHBhc3RlMCgibXUqUyIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChTKQogICAgICAgIHBhc3RlMCgibXUqRSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChFKQogICAgICAgIHBhc3RlMCgibXUqSSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChJKQogICAgICAgIHBhc3RlMCgibXUqUiIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIChSKQogICAgICAgIHBhc3RlMCgiYWxwaGEqSSIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgRGVhdGhzIGZyb20gaW5mZWN0aW9uCiAgICAgICAgCiAgICAgICkKCmBgYAoKCiMjIyBSdW4gU2luZ2xlIFBvcHVsYXRpb24gTW9kZWwKYGBge3J9CgpFSUVfc2luZ2xlIDwtIEVJRShSMF9zaW5nbGUsIHBhcm1zKSAjIHByb3BvcnRpb24gb2YgZXhwZWN0ZWQgaW5mZWN0ZWRzIGF0IGVxdWlsaWJyaXVtCkVJRV9zaW5nbGUKCmV4cGV4dGVkX2luZmVjdGVkcyA8LSBFSUVfc2luZ2xlKk5fYSAjIG51bWJlciBvZiBleHBlY3RlZCBpbmZlY3RlZHMgYXQgZXF1aWxpYnJpdW0KZXhwZXh0ZWRfaW5mZWN0ZWRzCgpzcXJ0KE5fYSkgIyBtYWduaXR1ZGUgb2Ygb3NjaWxsYXRpb25zIApgYGAKCmBgYHtyfQojIFJ1biBzaW11bGF0aW9ucyB3aXRoIHRoZSBEaXJlY3QgbWV0aG9kCnNldC5zZWVkKDIxKQpvdXRfYSA8LSBzc2EoCiAgeDAgPSB4MF9hLAogIGEgPSBhLAogIG51ID0gbnUsCiAgcGFybXMgPSBwYXJtcywKICB0ZiA9IHRmLAogIG1ldGhvZCA9IHNzYS5kKCksCiAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgdmVyYm9zZSA9IEZBTFNFLAogIGNvbnNvbGVJbnRlcnZhbCA9IDEKKSAKCgoKIyMgRXh0cmEgUGxvdHMKcGxvdF9kYXRhX2EgPC0gb3V0X2EkZGF0YSAlPiUKICBhc190aWJibGUoKSAlPiUKICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgbXV0YXRlKHN0YXRlID0gZmFjdG9yKHN0YXRlLCBsZXZlbHMgPSBjKCJTIiwgIkUiLCAiSSIsICJSIiwgIk4iKSkpICMlPiUKICAjZmlsdGVyKHN0YXRlICE9ICJOIikKCnNpbmdsZV9wbG90X2EgPC0gZ2dwbG90KGRhdGEgPSBwbG90X2RhdGFfYSwgYWVzKHg9dCwgeT1jb3VudCwgY29sb3VyPXN0YXRlKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOCkrCiAgbGFicyh4PSJUaW1lIChEYXlzKSIsCiAgICAgICB5PSJOdW1iZXIgb2YgSW5kaXZpZHVhbHMiLCAKICAgICAgIGNvbG91cj0iU3RhdGUiKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBleHBleHRlZF9pbmZlY3RlZHMsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsKICB0aGVtZV9idygpCgpzaW5nbGVfcGxvdF9hCmBgYAoKYGBge3J9CnBsb3RfZGF0YV9hICU+JQogIGZpbHRlcihzdGF0ZSA9PSAiSSIpICU+JQogIHNsaWNlX21heChjb3VudCkKYGBgCk91dGJyZWFrIHBlYWtlZCBhdCBkYXkgMzIgd2l0aCAzMSBpbmZlY3RlZCBpbmRpdmlkdWFscy4KCmBgYHtyfQojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF9hIDwtIGxpc3QoKQpzaW1fbGlzdF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIAogIE5fYSA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYSA8LSBjKE5fYSAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYSkKCiAgbmFtZXMoeDBfYSkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBzZXQuc2VlZChpKQogIG91dF8xMDBfYSA8LSBzc2EoCiAgICB4MCA9IHgwX2EsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfYSA8LSBvdXRfMTAwX2EkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0X2FbW2ldXSA8LSBzaW1fZGF0YV9hCn0KCnNpbV9vdXRwdXRfYSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF9hIDwtIHNpbV9vdXRwdXRfYSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCmhlYWQoc2ltX291dHB1dF9hKQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5X2EgPC0gc2ltX291dHB1dF9hICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsIAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTAwKQpzaW1fc3VtbWFyeV9hCmBgYAoKIyMjIFZhcnlpbmcgd2FpbmluZyBpbW11bml0eSB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KV2FuaW5nIGltbXVuaXR5IHdhcyB0aG91Z2h0IHRvIHBsYXkgYW4gaW1wb3J0YW50IHJvbGUgaW4gdGhlIHBlcnNpc3RlbmNlIG9mIHBhdGhvZ2VuIFggc28gd2UgaW5jcmVtZW50YWxseSBpbmNyZWFzZWQgdGhlIGR1cmF0aW9uIG9mIGltbXVuaXR5IChieSBkZWNyZWFzaW5nICRcb21lZ2EkKSBhbmQgY2FsY3VsYXRlZCB0aGUgcHJvYmFiaWxpdHkgb2YgcGVyc2lzdGVuY2UgYWZ0ZXIgMyB5ZWFycyBpbiAxMDAwIHN0b2NoYXN0aWMgc2ltdWxhdGlvbnMuIER1cmF0aW9uIG9mIGltbXVuaXR5IHdhcyBpbmNyZWFzZWQgZnJvbSAxIGRheSB0byBhIHllYXIuCgojIyMjIDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18wIDwtIHBhcm1zCnBhcm1zXzAkb21lZ2EgPC0gMAoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMF9hIDwtIGxpc3QoKQpzaW1fbGlzdF8wX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8wX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18wLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMF9hIDwtIG91dF8xMDBfMF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8wX2FbW2ldXSA8LSBzaW1fZGF0YV8wX2EKfQoKc2ltX291dHB1dF8wX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzBfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8wX2EgPC0gc2ltX291dHB1dF8wX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzBfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzBfYSA8LSBzaW1fb3V0cHV0XzBfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV8wX2EKYGBgCgoKCgojIyMjIDEgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xIDwtIHBhcm1zCnBhcm1zXzEkb21lZ2EgPC0gMQoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMV9hIDwtIGxpc3QoKQpzaW1fbGlzdF8xX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMV9hIDwtIG91dF8xMDBfMV9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xX2FbW2ldXSA8LSBzaW1fZGF0YV8xX2EKfQoKc2ltX291dHB1dF8xX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzFfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xX2EgPC0gc2ltX291dHB1dF8xX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzFfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzFfYSA8LSBzaW1fb3V0cHV0XzFfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxKQpzaW1fc3VtbWFyeV8xX2EKYGBgCgoKCgoKIyMjIyAzIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMyA8LSBwYXJtcwpwYXJtc18zJG9tZWdhIDwtIDEvMwoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfM19hIDwtIGxpc3QoKQpzaW1fbGlzdF8zX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18zLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfM19hIDwtIG91dF8xMDBfM19hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8zX2FbW2ldXSA8LSBzaW1fZGF0YV8zX2EKfQoKc2ltX291dHB1dF8zX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzNfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zX2EgPC0gc2ltX291dHB1dF8zX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzNfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzNfYSA8LSBzaW1fb3V0cHV0XzNfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzMpCnNpbV9zdW1tYXJ5XzNfYQpgYGAKCiMjIyMgNyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzcgPC0gcGFybXMKcGFybXNfNyRvbWVnYSA8LSAxLzcKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzdfYSA8LSBsaXN0KCkKc2ltX2xpc3RfN19hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF83X2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc183LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfN19hIDwtIG91dF8xMDBfN19hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF83X2FbW2ldXSA8LSBzaW1fZGF0YV83X2EKfQoKc2ltX291dHB1dF83X2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzdfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF83X2EgPC0gc2ltX291dHB1dF83X2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzdfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzdfYSA8LSBzaW1fb3V0cHV0XzdfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcpCnNpbV9zdW1tYXJ5XzdfYQpgYGAKCiMjIyMgMTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xMCA8LSBwYXJtcwpwYXJtc18xMCRvbWVnYSA8LSAxLzEwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTBfYSA8LSBsaXN0KCkKc2ltX2xpc3RfMTBfYSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYSA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYSA8LSBjKE5fYSAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYSkKCiAgbmFtZXMoeDBfYSkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzEwX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzEwX2EgPC0gb3V0XzEwMF8xMF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMF9hW1tpXV0gPC0gc2ltX2RhdGFfMTBfYQp9CgpzaW1fb3V0cHV0XzEwX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEwX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTBfYSA8LSBzaW1fb3V0cHV0XzEwX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEwX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xMF9hIDwtIHNpbV9vdXRwdXRfMTBfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEwKQpzaW1fc3VtbWFyeV8xMF9hCmBgYAoKIyMjIyAyMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzIwIDwtIHBhcm1zCnBhcm1zXzIwJG9tZWdhIDwtIDEvMjAKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzIwX2EgPC0gbGlzdCgpCnNpbV9saXN0XzIwX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8yMF9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8yMF9hIDwtIG91dF8xMDBfMjBfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMjBfYVtbaV1dIDwtIHNpbV9kYXRhXzIwX2EKfQoKc2ltX291dHB1dF8yMF9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8yMF9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzIwX2EgPC0gc2ltX291dHB1dF8yMF9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8yMF9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMjBfYSA8LSBzaW1fb3V0cHV0XzIwX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMCkKc2ltX3N1bW1hcnlfMjBfYQpgYGAKCiMjIyMgMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zMCA8LSBwYXJtcwpwYXJtc18zMCRvbWVnYSA8LSAxLzMwCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zMF9hIDwtIGxpc3QoKQpzaW1fbGlzdF8zMF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMzBfYSA8LSBzc2EoCiAgICB4MCA9IHgwX2EsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMzBfYSA8LSBvdXRfMTAwXzMwX2EkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzMwX2FbW2ldXSA8LSBzaW1fZGF0YV8zMF9hCn0KCnNpbV9vdXRwdXRfMzBfYSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMzBfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zMF9hIDwtIHNpbV9vdXRwdXRfMzBfYSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMzBfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzMwX2EgPC0gc2ltX291dHB1dF8zMF9hICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzApCnNpbV9zdW1tYXJ5XzMwX2EKYGBgCgojIyMjIDQwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNDAgPC0gcGFybXMKcGFybXNfNDAkb21lZ2EgPC0gMS80MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzQwX2EgPC0gbGlzdCgpCnNpbV9saXN0XzQwX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF80MF9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNDAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV80MF9hIDwtIG91dF8xMDBfNDBfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNDBfYVtbaV1dIDwtIHNpbV9kYXRhXzQwX2EKfQoKc2ltX291dHB1dF80MF9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF80MF9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzQwX2EgPC0gc2ltX291dHB1dF80MF9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF80MF9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNDBfYSA8LSBzaW1fb3V0cHV0XzQwX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS80MCkKc2ltX3N1bW1hcnlfNDBfYQpgYGAKCiMjIyMgNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc181MCA8LSBwYXJtcwpwYXJtc181MCRvbWVnYSA8LSAxLzUwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNTBfYSA8LSBsaXN0KCkKc2ltX2xpc3RfNTBfYSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYSA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYSA8LSBjKE5fYSAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYSkKCiAgbmFtZXMoeDBfYSkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzUwX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc181MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzUwX2EgPC0gb3V0XzEwMF81MF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF81MF9hW1tpXV0gPC0gc2ltX2RhdGFfNTBfYQp9CgpzaW1fb3V0cHV0XzUwX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzUwX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNTBfYSA8LSBzaW1fb3V0cHV0XzUwX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzUwX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV81MF9hIDwtIHNpbV9vdXRwdXRfNTBfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzUwKQpzaW1fc3VtbWFyeV81MF9hCmBgYAoKIyMjIyA2MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzYwIDwtIHBhcm1zCnBhcm1zXzYwJG9tZWdhIDwtIDEvNjAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF82MF9hIDwtIGxpc3QoKQpzaW1fbGlzdF82MF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNjBfYSA8LSBzc2EoCiAgICB4MCA9IHgwX2EsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNjBfYSA8LSBvdXRfMTAwXzYwX2EkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzYwX2FbW2ldXSA8LSBzaW1fZGF0YV82MF9hCn0KCnNpbV9vdXRwdXRfNjBfYSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNjBfYSkKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF82MF9hIDwtIHNpbV9vdXRwdXRfNjBfYSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNjBfYQoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzYwX2EgPC0gc2ltX291dHB1dF82MF9hICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNjApCnNpbV9zdW1tYXJ5XzYwX2EKYGBgCgojIyMjIDcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNzAgPC0gcGFybXMKcGFybXNfNzAkb21lZ2EgPC0gMS83MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzcwX2EgPC0gbGlzdCgpCnNpbV9saXN0XzcwX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF83MF9hIDwtIHNzYSgKICAgIHgwID0geDBfYSwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83MF9hIDwtIG91dF8xMDBfNzBfYSRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNzBfYVtbaV1dIDwtIHNpbV9kYXRhXzcwX2EKfQoKc2ltX291dHB1dF83MF9hIDwtIGJpbmRfcm93cyhzaW1fbGlzdF83MF9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzcwX2EgPC0gc2ltX291dHB1dF83MF9hICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF83MF9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNzBfYSA8LSBzaW1fb3V0cHV0XzcwX2EgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QpL251bV9zaW1zKSoxMDAsCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS83MCkKc2ltX3N1bW1hcnlfNzBfYQpgYGAKCiMjIyMgODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc184MCA8LSBwYXJtcwpwYXJtc184MCRvbWVnYSA8LSAxLzgwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfODBfYSA8LSBsaXN0KCkKc2ltX2xpc3RfODBfYSA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYSA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDMpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYSA8LSBjKE5fYSAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYSkKCiAgbmFtZXMoeDBfYSkgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzgwX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc184MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzgwX2EgPC0gb3V0XzEwMF84MF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF84MF9hW1tpXV0gPC0gc2ltX2RhdGFfODBfYQp9CgpzaW1fb3V0cHV0XzgwX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzgwX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfODBfYSA8LSBzaW1fb3V0cHV0XzgwX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzgwX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV84MF9hIDwtIHNpbV9vdXRwdXRfODBfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzgwKQpzaW1fc3VtbWFyeV84MF9hCmBgYAoKIyMjIyAxNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNTAgPC0gcGFybXMKcGFybXNfMTUwJG9tZWdhIDwtIDEvMTUwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTUwX2EgPC0gbGlzdCgpCnNpbV9saXN0XzE1MF9hIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9hIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9hIDwtIGMoTl9hIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9hKQoKICBuYW1lcyh4MF9hKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTUwX2EgPC0gc3NhKAogICAgeDAgPSB4MF9hLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xNTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xNTBfYSA8LSBvdXRfMTAwXzE1MF9hJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xNTBfYVtbaV1dIDwtIHNpbV9kYXRhXzE1MF9hCn0KCnNpbV9vdXRwdXRfMTUwX2EgPC0gYmluZF9yb3dzKHNpbV9saXN0XzE1MF9hKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzE1MF9hIDwtIHNpbV9vdXRwdXRfMTUwX2EgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzE1MF9hCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTUwX2EgPC0gc2ltX291dHB1dF8xNTBfYSAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzE1MCkKc2ltX3N1bW1hcnlfMTUwX2EKYGBgCgojIyMjIDE4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE4MCA8LSBwYXJtcwpwYXJtc18xODAkb21lZ2EgPC0gMS8xODAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xODBfYSA8LSBsaXN0KCkKc2ltX2xpc3RfMTgwX2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xODBfYSA8LSBzc2EoCiAgICB4MCA9IHgwX2EsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzE4MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE4MF9hIDwtIG91dF8xMDBfMTgwX2EkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE4MF9hW1tpXV0gPC0gc2ltX2RhdGFfMTgwX2EKfQoKc2ltX291dHB1dF8xODBfYSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTgwX2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTgwX2EgPC0gc2ltX291dHB1dF8xODBfYSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTgwX2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xODBfYSA8LSBzaW1fb3V0cHV0XzE4MF9hICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTgwKQpzaW1fc3VtbWFyeV8xODBfYQpgYGAKCgojIyMjIDM2NSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzM2NSA8LSBwYXJtcwpwYXJtc18zNjUkb21lZ2EgPC0gMS8zNjUKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zNjVfYSA8LSBsaXN0KCkKc2ltX2xpc3RfMzY1X2EgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2EgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAzKSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2EgPC0gYyhOX2EgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2EpCgogIG5hbWVzKHgwX2EpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zNjVfYSA8LSBzc2EoCiAgICB4MCA9IHgwX2EsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzM2NSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzM2NV9hIDwtIG91dF8xMDBfMzY1X2EkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzM2NV9hW1tpXV0gPC0gc2ltX2RhdGFfMzY1X2EKfQoKc2ltX291dHB1dF8zNjVfYSA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMzY1X2EpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMzY1X2EgPC0gc2ltX291dHB1dF8zNjVfYSAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMzY1X2EKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8zNjVfYSA8LSBzaW1fb3V0cHV0XzM2NV9hICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzY1KQpzaW1fc3VtbWFyeV8zNjVfYQpgYGAKCgoKIyMjIyBSZXN1bHRzCmBgYHtyfQp3YW5pbmdfcmVzdWx0c19zaW5nbGVfYSA8LSBzaW1fc3VtbWFyeV9hICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xX2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zX2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV83X2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xMF9hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMjBfYSkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzMwX2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV80MF9hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNTBfYSkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzYwX2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV83MF9hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfODBfYSkgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE1MF9hKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTgwX2EpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zNjVfYSkgJT4lCiAgbXV0YXRlKGltbXVuaXR5X2R1cmF0aW9uID0gMS9vbWVnYSkgJT4lCiAgYXJyYW5nZShpbW11bml0eV9kdXJhdGlvbikgJT4lCiAgbXV0YXRlKG1vZGVsPSJzaW5nbGUiLAogICAgICAgICBwYXRjaGVzID0gMykKCndyaXRlX2Nzdih3YW5pbmdfcmVzdWx0c19zaW5nbGVfYSwgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUmVzdWx0cy93YW5pbmdfcmVzdWx0c19zaW5nbGVfYS5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2EKCmBgYAoKYGBge3J9CmdncGxvdCh3YW5pbmdfcmVzdWx0c19zaW5nbGVfYSwgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfYncoKQpgYGAKCiMjIDctUGF0Y2ggU2luZ2xlIFBvcHVsYXRpb24KCiMjIyBNb2RlbCBTZXQtdXAKCk1vZGVsIHdhcyBzZXQgdXAgd2l0aCBhIHNpbmdsZSByYW5kb21seSBzZWxlY3RlZCBjYW1wIHNpemUgd2l0aCBhIHNpbmdsZSBpbmZlY3RlZCBpbmRpdmlkdWFsIGFuZCBwYXJhbWV0ZXJzIGZvciBwYXRob2dlbiBYLiAKCmBgYHtyfQojIERlZmluZSBQYXJhbWVudGVycwpOX2IgPC0gICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFBvcHVsYXRpb24gc2l6ZQppbml0aWFsX2luZmVjdGVkIDwtICAxICAgICMgSW5pdGlhbCBpbmZlY3RlZApzaW1OYW1lIDwtICJTRUlSUyBtb2RlbCIgICAgICAgIyBTaW11bGF0aW9uIG5hbWUKdGYgPC0gMzY1KjMKCiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXMgPC0gbGlzdCgKICBiZXRhID0gMC42LAogIHNpZ21hID0gMC4xNzUsICAgICAgICAgICAgICAgICAgICAgICAgICAjIEUgdG8gSSByYXRlCiAgZ2FtbWEgPSAwLjIsICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBJIHRvIFIgcmF0ZQogIG9tZWdhID0gMS8xMDAsICAgICAgICAgICAgICAgICAgICAgICAgICMgUiB0byBTIHJhdGUKICBtdSA9IGRlbW9fc3VtJEJpcnRoX3JhdGVfZGFpbHlfTWVhbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aC9kZWF0aCByYXRlIHBlciBwZXJzb24gcGVyIGRheQogIGFscGhhID0gMS8xMDAwKSAKCiNDcmVhdGUgdGhlIG5hbWVkIGluaXRpYWwgc3RhdGUgdmVjdG9yIGZvciB0aGUgVS1wYXRjaCBzeXN0ZW0uCgp4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKIyBEZWZpbmUgdGhlIHN0YXRlIGNoYW5nZSBtYXRyaXggZm9yIGEgc2luZ2xlIHBhdGNoCm51IDwtIG1hdHJpeChjKCAtMSwgIDAsICAwLCArMSwgKzEsIC0xLCAgMCwgIDAsICAwLCAgMCwgIyBTCiAgICAgICAgICAgICAgICArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICAwLCAgMCwgIyBFCiAgICAgICAgICAgICAgICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsIC0xLCAjIEkKICAgICAgICAgICAgICAgIDAsICAwLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAtMSwgIDAsICMgUiAKICAgICAgICAgICAgICAgIDAsICAwLCAgMCwgIDAsICsxLCAtMSAsLTEsIC0xLCAtMSwgLTEpLCAjIE4KICAgICAgICAgICAgIG5yb3c9NSxieXJvdz1UUlVFKQoKIyBEZWZpbmUgcHJvcGVuc2l0eSBmdW5jdGlvbnMKYSA8LWMoCiAgICAgICAgcGFzdGUwKCIoYmV0YSpJL04pKlMiKSwgIyBJbmZlY3Rpb24KICAgICAgICBwYXN0ZTAoInNpZ21hKkUiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJlY29tZXMgaW5mZWNpb3VzCiAgICAgICAgcGFzdGUwKCJnYW1tYSpJIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBSZWNvdmVyeSBmcm9tIGluZmVjdGlvbgogICAgICAgIHBhc3RlMCgib21lZ2EqUiIpLCAgICAgICAjIExvc3Mgb2YgaW1tdW5pdHkKICAgICAgICBwYXN0ZTAoIm11Kk4iKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmlydGhzCiAgICAgICAgcGFzdGUwKCJtdSpTIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFMpCiAgICAgICAgcGFzdGUwKCJtdSpFIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEUpCiAgICAgICAgcGFzdGUwKCJtdSpJIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKEkpCiAgICAgICAgcGFzdGUwKCJtdSpSIiksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgKFIpCiAgICAgICAgcGFzdGUwKCJhbHBoYSpJIikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBEZWF0aHMgZnJvbSBpbmZlY3Rpb24KICAgICAgICAKICAgICAgKQoKYGBgCgoKIyMjIFJ1biBTaW5nbGUgUG9wdWxhdGlvbiBNb2RlbApgYGB7cn0KCkVJRV9zaW5nbGUgPC0gRUlFKFIwX3NpbmdsZSwgcGFybXMpICMgcHJvcG9ydGlvbiBvZiBleHBlY3RlZCBpbmZlY3RlZHMgYXQgZXF1aWxpYnJpdW0KRUlFX3NpbmdsZQoKZXhwZXh0ZWRfaW5mZWN0ZWRzIDwtIEVJRV9zaW5nbGUqTl9iICMgbnVtYmVyIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpleHBleHRlZF9pbmZlY3RlZHMKCnNxcnQoTl9iKSAjIG1hZ25pdHVkZSBvZiBvc2NpbGxhdGlvbnMgCmBgYAoKYGBge3J9CiMgUnVuIHNpbXVsYXRpb25zIHdpdGggdGhlIERpcmVjdCBtZXRob2QKc2V0LnNlZWQoMjEpCm91dF9iIDwtIHNzYSgKICB4MCA9IHgwX2IsCiAgYSA9IGEsCiAgbnUgPSBudSwKICBwYXJtcyA9IHBhcm1zLAogIHRmID0gdGYsCiAgbWV0aG9kID0gc3NhLmQoKSwKICBzaW1OYW1lID0gc2ltTmFtZSwKICB2ZXJib3NlID0gRkFMU0UsCiAgY29uc29sZUludGVydmFsID0gMQopIAoKCgojIyBFeHRyYSBQbG90cwpwbG90X2RhdGFfYiA8LSBvdXRfYiRkYXRhICU+JQogIGFzX3RpYmJsZSgpICU+JQogIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICBtdXRhdGUoc3RhdGUgPSBmYWN0b3Ioc3RhdGUsIGxldmVscyA9IGMoIlMiLCAiRSIsICJJIiwgIlIiLCAiTiIpKSkgIyU+JQogICNmaWx0ZXIoc3RhdGUgIT0gIk4iKQoKc2luZ2xlX3Bsb3RfYiA8LSBnZ3Bsb3QoZGF0YSA9IHBsb3RfZGF0YV9iLCBhZXMoeD10LCB5PWNvdW50LCBjb2xvdXI9c3RhdGUpKSsKICBnZW9tX2xpbmUoYWxwaGE9MC44KSsKICBsYWJzKHg9IlRpbWUgKERheXMpIiwKICAgICAgIHk9Ik51bWJlciBvZiBJbmRpdmlkdWFscyIsIAogICAgICAgY29sb3VyPSJTdGF0ZSIpKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGV4cGV4dGVkX2luZmVjdGVkcywgbGluZXR5cGUgPSAnZGFzaGVkJykgKwogIHRoZW1lX2J3KCkKCnNpbmdsZV9wbG90X2IKYGBgCgpgYGB7cn0KcGxvdF9kYXRhX2IgJT4lCiAgZmlsdGVyKHN0YXRlID09ICJJIikgJT4lCiAgc2xpY2VfbWF4KGNvdW50KQpgYGAKT3V0YnJlYWsgcGVha2VkIGF0IGRheSAzMiB3aXRoIDMxIGluZmVjdGVkIGluZGl2aWR1YWxzLgoKYGBge3J9CiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0X2IgPC0gbGlzdCgpCnNpbV9saXN0X2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIHNldC5zZWVkKGkpCiAgb3V0XzEwMF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9iIDwtIG91dF8xMDBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfYltbaV1dIDwtIHNpbV9kYXRhX2IKfQoKc2ltX291dHB1dF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X2IgPC0gc2ltX291dHB1dF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKaGVhZChzaW1fb3V0cHV0X2IpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfYiA8LSBzaW1fb3V0cHV0X2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMDApCnNpbV9zdW1tYXJ5X2IKYGBgCgojIyMgVmFyeWluZyB3YWluaW5nIGltbXVuaXR5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQpXYW5pbmcgaW1tdW5pdHkgd2FzIHRob3VnaHQgdG8gcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiB0aGUgcGVyc2lzdGVuY2Ugb2YgcGF0aG9nZW4gWCBzbyB3ZSBpbmNyZW1lbnRhbGx5IGluY3JlYXNlZCB0aGUgZHVyYXRpb24gb2YgaW1tdW5pdHkgKGJ5IGRlY3JlYXNpbmcgJFxvbWVnYSQpIGFuZCBjYWxjdWxhdGVkIHRoZSBwcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzIGluIDEwMDAgc3RvY2hhc3RpYyBzaW11bGF0aW9ucy4gRHVyYXRpb24gb2YgaW1tdW5pdHkgd2FzIGluY3JlYXNlZCBmcm9tIDEgZGF5IHRvIGEgeWVhci4KCiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzAgPC0gcGFybXMKcGFybXNfMCRvbWVnYSA8LSAwCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8wX2IgPC0gbGlzdCgpCnNpbV9saXN0XzBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8wX2IgPC0gb3V0XzEwMF8wX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzBfYltbaV1dIDwtIHNpbV9kYXRhXzBfYgp9CgpzaW1fb3V0cHV0XzBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzBfYiA8LSBzaW1fb3V0cHV0XzBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMF9iIDwtIHNpbV9vdXRwdXRfMF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDApCnNpbV9zdW1tYXJ5XzBfYgpgYGAKCgoKCiMjIyMgMSBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEgPC0gcGFybXMKcGFybXNfMSRvbWVnYSA8LSAxCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xX2IgPC0gbGlzdCgpCnNpbV9saXN0XzFfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzFfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzEsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xX2IgPC0gb3V0XzEwMF8xX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzFfYltbaV1dIDwtIHNpbV9kYXRhXzFfYgp9CgpzaW1fb3V0cHV0XzFfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMV9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzFfYiA8LSBzaW1fb3V0cHV0XzFfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMV9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMV9iIDwtIHNpbV9vdXRwdXRfMV9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEpCnNpbV9zdW1tYXJ5XzFfYgpgYGAKCgoKCgojIyMjIDMgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zIDwtIHBhcm1zCnBhcm1zXzMkb21lZ2EgPC0gMS8zCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8zX2IgPC0gbGlzdCgpCnNpbV9saXN0XzNfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzNfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX2IgPC0gb3V0XzEwMF8zX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfYltbaV1dIDwtIHNpbV9kYXRhXzNfYgp9CgpzaW1fb3V0cHV0XzNfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfYiA8LSBzaW1fb3V0cHV0XzNfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19iIDwtIHNpbV9vdXRwdXRfM19iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMykKc2ltX3N1bW1hcnlfM19iCmBgYAoKIyMjIyA3IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNyA8LSBwYXJtcwpwYXJtc183JG9tZWdhIDwtIDEvNwoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfN19iIDwtIGxpc3QoKQpzaW1fbGlzdF83X2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzdfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzcsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV83X2IgPC0gb3V0XzEwMF83X2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzdfYltbaV1dIDwtIHNpbV9kYXRhXzdfYgp9CgpzaW1fb3V0cHV0XzdfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfN19iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzdfYiA8LSBzaW1fb3V0cHV0XzdfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfN19iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfN19iIDwtIHNpbV9vdXRwdXRfN19iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNykKc2ltX3N1bW1hcnlfN19iCmBgYAoKIyMjIyAxMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzEwIDwtIHBhcm1zCnBhcm1zXzEwJG9tZWdhIDwtIDEvMTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMF9iIDwtIGxpc3QoKQpzaW1fbGlzdF8xMF9iIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTBfYiA8LSBvdXRfMTAwXzEwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzEwX2JbW2ldXSA8LSBzaW1fZGF0YV8xMF9iCn0KCnNpbV9vdXRwdXRfMTBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xMF9iIDwtIHNpbV9vdXRwdXRfMTBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEwX2IgPC0gc2ltX291dHB1dF8xMF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTApCnNpbV9zdW1tYXJ5XzEwX2IKYGBgCgojIyMjIDIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMjAgPC0gcGFybXMKcGFybXNfMjAkb21lZ2EgPC0gMS8yMAoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMjBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfMjBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzIwX2IgPC0gc3NhKAogICAgeDAgPSB4MF9iLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzIwX2IgPC0gb3V0XzEwMF8yMF9iJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8yMF9iW1tpXV0gPC0gc2ltX2RhdGFfMjBfYgp9CgpzaW1fb3V0cHV0XzIwX2IgPC0gYmluZF9yb3dzKHNpbV9saXN0XzIwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMjBfYiA8LSBzaW1fb3V0cHV0XzIwX2IgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzIwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8yMF9iIDwtIHNpbV9vdXRwdXRfMjBfYiAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV8yMF9iCmBgYAoKIyMjIyAzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzMwIDwtIHBhcm1zCnBhcm1zXzMwJG9tZWdhIDwtIDEvMzAKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzMwX2IgPC0gbGlzdCgpCnNpbV9saXN0XzMwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8zMF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zMF9iIDwtIG91dF8xMDBfMzBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzBfYltbaV1dIDwtIHNpbV9kYXRhXzMwX2IKfQoKc2ltX291dHB1dF8zMF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zMF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzMwX2IgPC0gc2ltX291dHB1dF8zMF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zMF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMzBfYiA8LSBzaW1fb3V0cHV0XzMwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zMCkKc2ltX3N1bW1hcnlfMzBfYgpgYGAKCiMjIyMgNDAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc180MCA8LSBwYXJtcwpwYXJtc180MCRvbWVnYSA8LSAxLzQwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNDBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfNDBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzQwX2IgPC0gc3NhKAogICAgeDAgPSB4MF9iLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc180MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzQwX2IgPC0gb3V0XzEwMF80MF9iJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF80MF9iW1tpXV0gPC0gc2ltX2RhdGFfNDBfYgp9CgpzaW1fb3V0cHV0XzQwX2IgPC0gYmluZF9yb3dzKHNpbV9saXN0XzQwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNDBfYiA8LSBzaW1fb3V0cHV0XzQwX2IgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzQwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV80MF9iIDwtIHNpbV9vdXRwdXRfNDBfYiAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzQwKQpzaW1fc3VtbWFyeV80MF9iCmBgYAoKIyMjIyA1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzUwIDwtIHBhcm1zCnBhcm1zXzUwJG9tZWdhIDwtIDEvNTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF81MF9iIDwtIGxpc3QoKQpzaW1fbGlzdF81MF9iIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNTBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNTBfYiA8LSBvdXRfMTAwXzUwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzUwX2JbW2ldXSA8LSBzaW1fZGF0YV81MF9iCn0KCnNpbV9vdXRwdXRfNTBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNTBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF81MF9iIDwtIHNpbV9vdXRwdXRfNTBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNTBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzUwX2IgPC0gc2ltX291dHB1dF81MF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5XzUwX2IKYGBgCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNjAgPC0gcGFybXMKcGFybXNfNjAkb21lZ2EgPC0gMS82MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzYwX2IgPC0gbGlzdCgpCnNpbV9saXN0XzYwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF82MF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfNjAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV82MF9iIDwtIG91dF8xMDBfNjBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfNjBfYltbaV1dIDwtIHNpbV9kYXRhXzYwX2IKfQoKc2ltX291dHB1dF82MF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF82MF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzYwX2IgPC0gc2ltX291dHB1dF82MF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF82MF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfNjBfYiA8LSBzaW1fb3V0cHV0XzYwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS82MCkKc2ltX3N1bW1hcnlfNjBfYgpgYGAKCiMjIyMgNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc183MCA8LSBwYXJtcwpwYXJtc183MCRvbWVnYSA8LSAxLzcwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfNzBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfNzBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzcwX2IgPC0gc3NhKAogICAgeDAgPSB4MF9iLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc183MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzcwX2IgPC0gb3V0XzEwMF83MF9iJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF83MF9iW1tpXV0gPC0gc2ltX2RhdGFfNzBfYgp9CgpzaW1fb3V0cHV0XzcwX2IgPC0gYmluZF9yb3dzKHNpbV9saXN0XzcwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfNzBfYiA8LSBzaW1fb3V0cHV0XzcwX2IgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzcwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV83MF9iIDwtIHNpbV9vdXRwdXRfNzBfYiAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCkvbnVtX3NpbXMpKjEwMCwKICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcwKQpzaW1fc3VtbWFyeV83MF9iCmBgYAoKIyMjIyA4MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzgwIDwtIHBhcm1zCnBhcm1zXzgwJG9tZWdhIDwtIDEvODAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF84MF9iIDwtIGxpc3QoKQpzaW1fbGlzdF84MF9iIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfODBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfODBfYiA8LSBvdXRfMTAwXzgwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzgwX2JbW2ldXSA8LSBzaW1fZGF0YV84MF9iCn0KCnNpbV9vdXRwdXRfODBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfODBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF84MF9iIDwtIHNpbV9vdXRwdXRfODBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfODBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzgwX2IgPC0gc2ltX291dHB1dF84MF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvODApCnNpbV9zdW1tYXJ5XzgwX2IKYGBgCgojIyMjIDkwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfOTAgPC0gcGFybXMKcGFybXNfOTAkb21lZ2EgPC0gMS85MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzkwX2IgPC0gbGlzdCgpCnNpbV9saXN0XzkwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF85MF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfOTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV85MF9iIDwtIG91dF8xMDBfOTBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfOTBfYltbaV1dIDwtIHNpbV9kYXRhXzkwX2IKfQoKc2ltX291dHB1dF85MF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF85MF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzkwX2IgPC0gc2ltX291dHB1dF85MF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF85MF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfOTBfYiA8LSBzaW1fb3V0cHV0XzkwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS85MCkKc2ltX3N1bW1hcnlfOTBfYgpgYGAKCgojIyMjIDExMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzExMCA8LSBwYXJtcwpwYXJtc18xMTAkb21lZ2EgPC0gMS8xMTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xMTBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfMTEwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xMTBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzExMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzExMF9iIDwtIG91dF8xMDBfMTEwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzExMF9iW1tpXV0gPC0gc2ltX2RhdGFfMTEwX2IKfQoKc2ltX291dHB1dF8xMTBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTEwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTEwX2IgPC0gc2ltX291dHB1dF8xMTBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTEwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xMTBfYiA8LSBzaW1fb3V0cHV0XzExMF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTEwKQpzaW1fc3VtbWFyeV8xMTBfYgpgYGAKCiMjIyMgMTIwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTIwIDwtIHBhcm1zCnBhcm1zXzEyMCRvbWVnYSA8LSAxLzEyMAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzEyMF9iIDwtIGxpc3QoKQpzaW1fbGlzdF8xMjBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzEyMF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTIwX2IgPC0gb3V0XzEwMF8xMjBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTIwX2JbW2ldXSA8LSBzaW1fZGF0YV8xMjBfYgp9CgpzaW1fb3V0cHV0XzEyMF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xMjBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xMjBfYiA8LSBzaW1fb3V0cHV0XzEyMF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xMjBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEyMF9iIDwtIHNpbV9vdXRwdXRfMTIwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMjApCnNpbV9zdW1tYXJ5XzEyMF9iCmBgYAoKIyMjIyAxMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xMzAgPC0gcGFybXMKcGFybXNfMTMwJG9tZWdhIDwtIDEvMTMwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTMwX2IgPC0gbGlzdCgpCnNpbV9saXN0XzEzMF9iIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9iIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgNykpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9iIDwtIGMoTl9iIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9iKQoKICBuYW1lcyh4MF9iKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMTMwX2IgPC0gc3NhKAogICAgeDAgPSB4MF9iLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18xMzAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMzBfYiA8LSBvdXRfMTAwXzEzMF9iJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8xMzBfYltbaV1dIDwtIHNpbV9kYXRhXzEzMF9iCn0KCnNpbV9vdXRwdXRfMTMwX2IgPC0gYmluZF9yb3dzKHNpbV9saXN0XzEzMF9iKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEzMF9iIDwtIHNpbV9vdXRwdXRfMTMwX2IgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzEzMF9iCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTMwX2IgPC0gc2ltX291dHB1dF8xMzBfYiAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzEzMCkKc2ltX3N1bW1hcnlfMTMwX2IKYGBgCgojIyMjIDE1MCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzE1MCA8LSBwYXJtcwpwYXJtc18xNTAkb21lZ2EgPC0gMS8xNTAKCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8xNTBfYiA8LSBsaXN0KCkKc2ltX2xpc3RfMTUwX2IgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2IgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCA3KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2IgPC0gYyhOX2IgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2IpCgogIG5hbWVzKHgwX2IpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xNTBfYiA8LSBzc2EoCiAgICB4MCA9IHgwX2IsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzE1MCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzE1MF9iIDwtIG91dF8xMDBfMTUwX2IkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzE1MF9iW1tpXV0gPC0gc2ltX2RhdGFfMTUwX2IKfQoKc2ltX291dHB1dF8xNTBfYiA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMTUwX2IpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMTUwX2IgPC0gc2ltX291dHB1dF8xNTBfYiAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMTUwX2IKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xNTBfYiA8LSBzaW1fb3V0cHV0XzE1MF9iICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMTUwKQpzaW1fc3VtbWFyeV8xNTBfYgpgYGAKCiMjIyMgMTgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMTgwIDwtIHBhcm1zCnBhcm1zXzE4MCRvbWVnYSA8LSAxLzE4MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzE4MF9iIDwtIGxpc3QoKQpzaW1fbGlzdF8xODBfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzE4MF9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTgwX2IgPC0gb3V0XzEwMF8xODBfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTgwX2JbW2ldXSA8LSBzaW1fZGF0YV8xODBfYgp9CgpzaW1fb3V0cHV0XzE4MF9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xODBfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xODBfYiA8LSBzaW1fb3V0cHV0XzE4MF9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xODBfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE4MF9iIDwtIHNpbV9vdXRwdXRfMTgwX2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xODApCnNpbV9zdW1tYXJ5XzE4MF9iCmBgYAoKCiMjIyMgMzY1IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfMzY1IDwtIHBhcm1zCnBhcm1zXzM2NSRvbWVnYSA8LSAxLzM2NQoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzM2NV9iIDwtIGxpc3QoKQpzaW1fbGlzdF8zNjVfYiA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYiA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDcpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYiA8LSBjKE5fYiAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYikKCiAgbmFtZXMoeDBfYikgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzM2NV9iIDwtIHNzYSgKICAgIHgwID0geDBfYiwKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMzY1LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMzY1X2IgPC0gb3V0XzEwMF8zNjVfYiRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzY1X2JbW2ldXSA8LSBzaW1fZGF0YV8zNjVfYgp9CgpzaW1fb3V0cHV0XzM2NV9iIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zNjVfYikKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zNjVfYiA8LSBzaW1fb3V0cHV0XzM2NV9iICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zNjVfYgoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzM2NV9iIDwtIHNpbV9vdXRwdXRfMzY1X2IgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzM2NV9iCmBgYAoKCgojIyMjIFJlc3VsdHMKYGBge3J9CndhbmluZ19yZXN1bHRzX3NpbmdsZV9iIDwtIHNpbV9zdW1tYXJ5X2IgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzFfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzdfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8yMF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMzBfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzQwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV81MF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNjBfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzcwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV84MF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfOTBfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzExMF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTIwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xMzBfYikgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE1MF9iKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTgwX2IpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8zNjVfYikgJT4lCiAgbXV0YXRlKGltbXVuaXR5X2R1cmF0aW9uID0gMS9vbWVnYSkgJT4lCiAgYXJyYW5nZShpbW11bml0eV9kdXJhdGlvbikgJT4lCiAgbXV0YXRlKG1vZGVsPSJzaW5nbGUiLAogICAgICAgICBwYXRjaGVzID0gNykKCndyaXRlX2Nzdih3YW5pbmdfcmVzdWx0c19zaW5nbGVfYiwgZmlsZSA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUmVzdWx0cy93YW5pbmdfcmVzdWx0c19zaW5nbGVfYi5jc3YiKQoKd2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2IKCmBgYAoKYGBge3J9CmdncGxvdCh3YW5pbmdfcmVzdWx0c19zaW5nbGVfYiwgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfYncoKQpgYGAKCiMjIDE0LVBhdGNoIFNpbmdsZSBQb3B1bGF0aW9uCgojIyMgTW9kZWwgU2V0LXVwCgpNb2RlbCB3YXMgc2V0IHVwIHdpdGggYSBzaW5nbGUgcmFuZG9tbHkgc2VsZWN0ZWQgY2FtcCBzaXplIHdpdGggYSBzaW5nbGUgaW5mZWN0ZWQgaW5kaXZpZHVhbCBhbmQgcGFyYW1ldGVycyBmb3IgcGF0aG9nZW4gWC4gCgpgYGB7cn0KIyBEZWZpbmUgUGFyYW1lbnRlcnMKTl9jIDwtICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgUG9wdWxhdGlvbiBzaXplCmluaXRpYWxfaW5mZWN0ZWQgPC0gIDEgICAgIyBJbml0aWFsIGluZmVjdGVkCnNpbU5hbWUgPC0gIlNFSVJTIG1vZGVsIiAgICAgICAjIFNpbXVsYXRpb24gbmFtZQp0ZiA8LSAzNjUqMwoKI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtcyA8LSBsaXN0KAogIGJldGEgPSAwLjYsCiAgc2lnbWEgPSAwLjE3NSwgICAgICAgICAgICAgICAgICAgICAgICAgICMgRSB0byBJIHJhdGUKICBnYW1tYSA9IDAuMiwgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEkgdG8gUiByYXRlCiAgb21lZ2EgPSAxLzEwMCwgICAgICAgICAgICAgICAgICAgICAgICAgIyBSIHRvIFMgcmF0ZQogIG11ID0gZGVtb19zdW0kQmlydGhfcmF0ZV9kYWlseV9NZWFuLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIEJpcnRoL2RlYXRoIHJhdGUgcGVyIHBlcnNvbiBwZXIgZGF5CiAgYWxwaGEgPSAxLzEwMDApIAoKI0NyZWF0ZSB0aGUgbmFtZWQgaW5pdGlhbCBzdGF0ZSB2ZWN0b3IgZm9yIHRoZSBVLXBhdGNoIHN5c3RlbS4KCngwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgpuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgojIERlZmluZSB0aGUgc3RhdGUgY2hhbmdlIG1hdHJpeCBmb3IgYSBzaW5nbGUgcGF0Y2gKbnUgPC0gbWF0cml4KGMoIC0xLCAgMCwgIDAsICsxLCArMSwgLTEsICAwLCAgMCwgIDAsICAwLCAjIFMKICAgICAgICAgICAgICAgICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIDAsICAwLCAjIEUKICAgICAgICAgICAgICAgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgLTEsICMgSQogICAgICAgICAgICAgICAgMCwgIDAsICsxLCAtMSwgIDAsICAwLCAgMCwgIDAsIC0xLCAgMCwgIyBSIAogICAgICAgICAgICAgICAgMCwgIDAsICAwLCAgMCwgKzEsIC0xICwtMSwgLTEsIC0xLCAtMSksICMgTgogICAgICAgICAgICAgbnJvdz01LGJ5cm93PVRSVUUpCgojIERlZmluZSBwcm9wZW5zaXR5IGZ1bmN0aW9ucwphIDwtYygKICAgICAgICBwYXN0ZTAoIihiZXRhKkkvTikqUyIpLCAjIEluZmVjdGlvbgogICAgICAgIHBhc3RlMCgic2lnbWEqRSIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgQmVjb21lcyBpbmZlY2lvdXMKICAgICAgICBwYXN0ZTAoImdhbW1hKkkiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIFJlY292ZXJ5IGZyb20gaW5mZWN0aW9uCiAgICAgICAgcGFzdGUwKCJvbWVnYSpSIiksICAgICAgICMgTG9zcyBvZiBpbW11bml0eQogICAgICAgIHBhc3RlMCgibXUqTiIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBCaXJ0aHMKICAgICAgICBwYXN0ZTAoIm11KlMiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUykKICAgICAgICBwYXN0ZTAoIm11KkUiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoRSkKICAgICAgICBwYXN0ZTAoIm11KkkiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoSSkKICAgICAgICBwYXN0ZTAoIm11KlIiKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyAoUikKICAgICAgICBwYXN0ZTAoImFscGhhKkkiKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIERlYXRocyBmcm9tIGluZmVjdGlvbgogICAgICAgIAogICAgICApCgpgYGAKCgojIyMgUnVuIFNpbmdsZSBQb3B1bGF0aW9uIE1vZGVsCmBgYHtyfQoKRUlFX3NpbmdsZSA8LSBFSUUoUjBfc2luZ2xlLCBwYXJtcykgIyBwcm9wb3J0aW9uIG9mIGV4cGVjdGVkIGluZmVjdGVkcyBhdCBlcXVpbGlicml1bQpFSUVfc2luZ2xlCgpleHBleHRlZF9pbmZlY3RlZHMgPC0gRUlFX3NpbmdsZSpOX2MgIyBudW1iZXIgb2YgZXhwZWN0ZWQgaW5mZWN0ZWRzIGF0IGVxdWlsaWJyaXVtCmV4cGV4dGVkX2luZmVjdGVkcwoKc3FydChOX2MpICMgbWFnbml0dWRlIG9mIG9zY2lsbGF0aW9ucyAKYGBgCgpgYGB7cn0KIyBSdW4gc2ltdWxhdGlvbnMgd2l0aCB0aGUgRGlyZWN0IG1ldGhvZApzZXQuc2VlZCgyMSkKb3V0X2MgPC0gc3NhKAogIHgwID0geDBfYywKICBhID0gYSwKICBudSA9IG51LAogIHBhcm1zID0gcGFybXMsCiAgdGYgPSB0ZiwKICBtZXRob2QgPSBzc2EuZCgpLAogIHNpbU5hbWUgPSBzaW1OYW1lLAogIHZlcmJvc2UgPSBGQUxTRSwKICBjb25zb2xlSW50ZXJ2YWwgPSAxCikgCgoKCiMjIEV4dHJhIFBsb3RzCnBsb3RfZGF0YV9jIDwtIG91dF9jJGRhdGEgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogIG11dGF0ZShzdGF0ZSA9IGZhY3RvcihzdGF0ZSwgbGV2ZWxzID0gYygiUyIsICJFIiwgIkkiLCAiUiIsICJOIikpKSAjJT4lCiAgI2ZpbHRlcihzdGF0ZSAhPSAiTiIpCgpzaW5nbGVfcGxvdF9jIDwtIGdncGxvdChkYXRhID0gcGxvdF9kYXRhX2MsIGFlcyh4PXQsIHk9Y291bnQsIGNvbG91cj1zdGF0ZSkpKwogIGdlb21fbGluZShhbHBoYT0wLjgpKwogIGxhYnMoeD0iVGltZSAoRGF5cykiLAogICAgICAgeT0iTnVtYmVyIG9mIEluZGl2aWR1YWxzIiwgCiAgICAgICBjb2xvdXI9IlN0YXRlIikrCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZXhwZXh0ZWRfaW5mZWN0ZWRzLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArCiAgdGhlbWVfYncoKQoKc2luZ2xlX3Bsb3RfYwpgYGAKCmBgYHtyfQpwbG90X2RhdGFfYyAlPiUKICBmaWx0ZXIoc3RhdGUgPT0gIkkiKSAlPiUKICBzbGljZV9tYXgoY291bnQpCmBgYApPdXRicmVhayBwZWFrZWQgYXQgZGF5IDMyIHdpdGggMzEgaW5mZWN0ZWQgaW5kaXZpZHVhbHMuCgpgYGB7cn0KIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfYyA8LSBsaXN0KCkKc2ltX2xpc3RfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIHNldC5zZWVkKGkpCiAgb3V0XzEwMF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV9jIDwtIG91dF8xMDBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfY1tbaV1dIDwtIHNpbV9kYXRhX2MKfQoKc2ltX291dHB1dF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0X2MgPC0gc2ltX291dHB1dF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKaGVhZChzaW1fb3V0cHV0X2MpCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfYyA8LSBzaW1fb3V0cHV0X2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMDApCnNpbV9zdW1tYXJ5X2MKYGBgCgojIyMgVmFyeWluZyB3YWluaW5nIGltbXVuaXR5IHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQpXYW5pbmcgaW1tdW5pdHkgd2FzIHRob3VnaHQgdG8gcGxheSBhbiBpbXBvcnRhbnQgcm9sZSBpbiB0aGUgcGVyc2lzdGVuY2Ugb2YgcGF0aG9nZW4gWCBzbyB3ZSBpbmNyZW1lbnRhbGx5IGluY3JlYXNlZCB0aGUgZHVyYXRpb24gb2YgaW1tdW5pdHkgKGJ5IGRlY3JlYXNpbmcgJFxvbWVnYSQpIGFuZCBjYWxjdWxhdGVkIHRoZSBwcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzIGluIDEwMDAgc3RvY2hhc3RpYyBzaW11bGF0aW9ucy4gRHVyYXRpb24gb2YgaW1tdW5pdHkgd2FzIGluY3JlYXNlZCBmcm9tIDEgZGF5IHRvIGEgeWVhci4KCiMjIyMgMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzAgPC0gcGFybXMKcGFybXNfMCRvbWVnYSA8LSAwCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8wX2MgPC0gbGlzdCgpCnNpbV9saXN0XzBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8wX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18wLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMF9jIDwtIG91dF8xMDBfMF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8wX2NbW2ldXSA8LSBzaW1fZGF0YV8wX2MKfQoKc2ltX291dHB1dF8wX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8wX2MgPC0gc2ltX291dHB1dF8wX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzBfYyA8LSBzaW1fb3V0cHV0XzBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAwKQpzaW1fc3VtbWFyeV8wX2MKYGBgCgoKCgojIyMjIDEgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xIDwtIHBhcm1zCnBhcm1zXzEkb21lZ2EgPC0gMQoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMV9jIDwtIGxpc3QoKQpzaW1fbGlzdF8xX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMV9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMSwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzFfYyA8LSBvdXRfMTAwXzFfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMV9jW1tpXV0gPC0gc2ltX2RhdGFfMV9jCn0KCnNpbV9vdXRwdXRfMV9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xX2MpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMV9jIDwtIHNpbV9vdXRwdXRfMV9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xX2MKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8xX2MgPC0gc2ltX291dHB1dF8xX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMSkKc2ltX3N1bW1hcnlfMV9jCmBgYAoKCgoKCiMjIyMgMyBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzMgPC0gcGFybXMKcGFybXNfMyRvbWVnYSA8LSAxLzMKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzNfYyA8LSBsaXN0KCkKc2ltX2xpc3RfM19jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzNfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8zX2MgPC0gb3V0XzEwMF8zX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzNfY1tbaV1dIDwtIHNpbV9kYXRhXzNfYwp9CgpzaW1fb3V0cHV0XzNfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfM19jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzNfYyA8LSBzaW1fb3V0cHV0XzNfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfM19jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfM19jIDwtIHNpbV9vdXRwdXRfM19jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMykKc2ltX3N1bW1hcnlfM19jCmBgYAoKIyMjIyA3IERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNyA8LSBwYXJtcwpwYXJtc183JG9tZWdhIDwtIDEvNwoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfN19jIDwtIGxpc3QoKQpzaW1fbGlzdF83X2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF83X2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc183LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfN19jIDwtIG91dF8xMDBfN19jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF83X2NbW2ldXSA8LSBzaW1fZGF0YV83X2MKfQoKc2ltX291dHB1dF83X2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzdfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF83X2MgPC0gc2ltX291dHB1dF83X2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzdfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzdfYyA8LSBzaW1fb3V0cHV0XzdfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzcpCnNpbV9zdW1tYXJ5XzdfYwpgYGAKCiMjIyMgMTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xMCA8LSBwYXJtcwpwYXJtc18xMCRvbWVnYSA8LSAxLzEwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTBfYyA8LSBsaXN0KCkKc2ltX2xpc3RfMTBfYyA8LSB2ZWN0b3IoImxpc3QiLCBsZW5ndGggPSBudW1fc2ltcykKCmZvciAoaSBpbiAxOm51bV9zaW1zKXsKICBzZXQuc2VlZChpKQogIAogIE5fYyA8LSAgICAgc3VtKHNhbXBsZShjYW1wcy5kYXRhJGNhbXBfdG90YWwsIDE0KSkgICAgIyBTYW1wbGUgZGlmZmVyZW50IHBhdGNoIHNpemVzIGZvciBlYWNoIHNpbQogIAogIHgwX2MgPC0gYyhOX2MgLSBpbml0aWFsX2luZmVjdGVkLCBpbml0aWFsX2luZmVjdGVkLCAwLCAwLCBOX2MpCgogIG5hbWVzKHgwX2MpIDwtIGMoIlMiLCJFIiwiSSIsICJSIiwgIk4iKQoKCiAgb3V0XzEwMF8xMF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTAsCiAgICB0ZiA9IHRmLAogICAgbWV0aG9kID0gc3NhLmQoKSwKICAgIHNpbU5hbWUgPSBzaW1OYW1lLAogICAgdmVyYm9zZSA9IEZBTFNFLAogICAgY29uc29sZUludGVydmFsID0gMQogICkKCiAgCiMgRXh0cmFjdCBGaW5hbCB0aW1lIHBvaW50IGZyb20gb3V0cHV0IGRhdGEKICBzaW1fZGF0YV8xMF9jIDwtIG91dF8xMDBfMTBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTBfY1tbaV1dIDwtIHNpbV9kYXRhXzEwX2MKfQoKc2ltX291dHB1dF8xMF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xMF9jKQpgYGAKCmBgYHtyfQojIFN1bW1hcnkgdGFibGUgb2YgZW5kcG9pbnQgZGF0YQpzaW1fb3V0cHV0XzEwX2MgPC0gc2ltX291dHB1dF8xMF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xMF9jCgojIE1ha2UgU3VtbWFyeSBUYWJsZSBvZiBvdXRwdXQKc2ltX3N1bW1hcnlfMTBfYyA8LSBzaW1fb3V0cHV0XzEwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMCkKc2ltX3N1bW1hcnlfMTBfYwpgYGAKCiMjIyMgMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18yMCA8LSBwYXJtcwpwYXJtc18yMCRvbWVnYSA8LSAxLzIwCgojIyBSdW4gbXVsdGlwbGUgc2ltdWxhdGlvbnMgYW5kIHNhdmluZyBvdXRwdXQKbnVtX3NpbXMgPC0gMTAwMApzaW1fbGlzdF8yMF9jIDwtIGxpc3QoKQpzaW1fbGlzdF8yMF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzIwX2MgPC0gc3NhKAogICAgeDAgPSB4MF9jLAogICAgYSA9IGEsCiAgICBudSA9IG51LAogICAgcGFybXMgPSBwYXJtc18yMCwKICAgIHRmID0gdGYsCiAgICBtZXRob2QgPSBzc2EuZCgpLAogICAgc2ltTmFtZSA9IHNpbU5hbWUsCiAgICB2ZXJib3NlID0gRkFMU0UsCiAgICBjb25zb2xlSW50ZXJ2YWwgPSAxCiAgKQoKICAKIyBFeHRyYWN0IEZpbmFsIHRpbWUgcG9pbnQgZnJvbSBvdXRwdXQgZGF0YQogIHNpbV9kYXRhXzIwX2MgPC0gb3V0XzEwMF8yMF9jJGRhdGEgJT4lCiAgICBhc190aWJibGUoKSAlPiUKICAgIHNsaWNlX21heCh0KSAlPiUKICAgIGRpc3RpbmN0KCkgJT4lCiAgICBwaXZvdF9sb25nZXIoIXQsIG5hbWVzX3RvID0gInN0YXRlIiwgdmFsdWVzX3RvID0gImNvdW50IikgJT4lCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gc3RhdGUsIHZhbHVlc19mcm9tID0gY291bnQpICU+JQogICAgbXV0YXRlKHBlcnNpc3QgPSBjYXNlX3doZW4oSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEkgPT0gMCB+IEYpLAogICAgICAgICAgIHNpbSA9IGkpICU+JQogICAgc2VsZWN0KHNpbSwgSSwgTiwgcGVyc2lzdCkKICAKICBzaW1fbGlzdF8yMF9jW1tpXV0gPC0gc2ltX2RhdGFfMjBfYwp9CgpzaW1fb3V0cHV0XzIwX2MgPC0gYmluZF9yb3dzKHNpbV9saXN0XzIwX2MpCmBgYAoKYGBge3J9CiMgU3VtbWFyeSB0YWJsZSBvZiBlbmRwb2ludCBkYXRhCnNpbV9vdXRwdXRfMjBfYyA8LSBzaW1fb3V0cHV0XzIwX2MgJT4lCiAgZ3JvdXBfYnkoc2ltKSAlPiUKICBzdW1tYXJpc2UodG90YWxfSSA9IHN1bShJKSwgCiAgICAgICAgICAgIHRvdGFsX04gPSBzdW0oTikpICU+JQogIG11dGF0ZShwZXJjZW50X3BlcnNpc3QgPSB0b3RhbF9JLyh0b3RhbF9OKSoxMDAsCiAgICAgICAgIHBlcnNpc3QgPSBjYXNlX3doZW4odG90YWxfSSA+IDAgfiBULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsX0kgPT0gMCB+IEYpKQpzaW1fb3V0cHV0XzIwX2MKCiMgTWFrZSBTdW1tYXJ5IFRhYmxlIG9mIG91dHB1dApzaW1fc3VtbWFyeV8yMF9jIDwtIHNpbV9vdXRwdXRfMjBfYyAlPiUKICBzdW1tYXJpc2UobWVhbl9pbmZlY3RlZHMgPSBtZWFuKHRvdGFsX0kpLAogICAgICAgICAgICBzdW1fcGVyc2lzdCA9IChzdW0ocGVyc2lzdCwgbmEucm0gPSBUKS9udW1fc2ltcykqMTAwLCAgICAgICAgICAgICAgbWVhbl9wZXJjZW50X2luZmVjdGVkID0gbWVhbihwZXJjZW50X3BlcnNpc3QpKSAlPiUKICBtdXRhdGUob21lZ2EgPSAxLzIwKQpzaW1fc3VtbWFyeV8yMF9jCmBgYAoKIyMjIyAzMCBEYXlzCmBgYHtyfQojQ29sbGVjdCBwYXJhbWV0ZXJzCnBhcm1zXzMwIDwtIHBhcm1zCnBhcm1zXzMwJG9tZWdhIDwtIDEvMzAKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzMwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzMwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfMzBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMzBfYyA8LSBvdXRfMTAwXzMwX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzMwX2NbW2ldXSA8LSBzaW1fZGF0YV8zMF9jCn0KCnNpbV9vdXRwdXRfMzBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfMzBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zMF9jIDwtIHNpbV9vdXRwdXRfMzBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfMzBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzMwX2MgPC0gc2ltX291dHB1dF8zMF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvMzApCnNpbV9zdW1tYXJ5XzMwX2MKYGBgCgojIyMjIDQwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNDAgPC0gcGFybXMKcGFybXNfNDAkb21lZ2EgPC0gMS80MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzQwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzQwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNDBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzQwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNDBfYyA8LSBvdXRfMTAwXzQwX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzQwX2NbW2ldXSA8LSBzaW1fZGF0YV80MF9jCn0KCnNpbV9vdXRwdXRfNDBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNDBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF80MF9jIDwtIHNpbV9vdXRwdXRfNDBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNDBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzQwX2MgPC0gc2ltX291dHB1dF80MF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNDApCnNpbV9zdW1tYXJ5XzQwX2MKYGBgCgojIyMjIDUwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNTAgPC0gcGFybXMKcGFybXNfNTAkb21lZ2EgPC0gMS81MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzUwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzUwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNTBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNTBfYyA8LSBvdXRfMTAwXzUwX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzUwX2NbW2ldXSA8LSBzaW1fZGF0YV81MF9jCn0KCnNpbV9vdXRwdXRfNTBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNTBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF81MF9jIDwtIHNpbV9vdXRwdXRfNTBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNTBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzUwX2MgPC0gc2ltX291dHB1dF81MF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNTApCnNpbV9zdW1tYXJ5XzUwX2MKYGBgCgojIyMjIDYwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNjAgPC0gcGFybXMKcGFybXNfNjAkb21lZ2EgPC0gMS82MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzYwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzYwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNjBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzYwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNjBfYyA8LSBvdXRfMTAwXzYwX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzYwX2NbW2ldXSA8LSBzaW1fZGF0YV82MF9jCn0KCnNpbV9vdXRwdXRfNjBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNjBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF82MF9jIDwtIHNpbV9vdXRwdXRfNjBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNjBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzYwX2MgPC0gc2ltX291dHB1dF82MF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNjApCnNpbV9zdW1tYXJ5XzYwX2MKYGBgCgojIyMjIDcwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfNzAgPC0gcGFybXMKcGFybXNfNzAkb21lZ2EgPC0gMS83MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzcwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzcwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfNzBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfNzBfYyA8LSBvdXRfMTAwXzcwX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzcwX2NbW2ldXSA8LSBzaW1fZGF0YV83MF9jCn0KCnNpbV9vdXRwdXRfNzBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfNzBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF83MF9jIDwtIHNpbV9vdXRwdXRfNzBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfNzBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzcwX2MgPC0gc2ltX291dHB1dF83MF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0KS9udW1fc2ltcykqMTAwLAogICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvNzApCnNpbV9zdW1tYXJ5XzcwX2MKYGBgCgojIyMjIDgwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfODAgPC0gcGFybXMKcGFybXNfODAkb21lZ2EgPC0gMS84MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzgwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzgwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfODBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfODBfYyA8LSBvdXRfMTAwXzgwX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzgwX2NbW2ldXSA8LSBzaW1fZGF0YV84MF9jCn0KCnNpbV9vdXRwdXRfODBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfODBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF84MF9jIDwtIHNpbV9vdXRwdXRfODBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfODBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzgwX2MgPC0gc2ltX291dHB1dF84MF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvODApCnNpbV9zdW1tYXJ5XzgwX2MKYGBgCgojIyMjIDkwIERheXMKYGBge3J9CiNDb2xsZWN0IHBhcmFtZXRlcnMKcGFybXNfOTAgPC0gcGFybXMKcGFybXNfOTAkb21lZ2EgPC0gMS85MAoKCiMjIFJ1biBtdWx0aXBsZSBzaW11bGF0aW9ucyBhbmQgc2F2aW5nIG91dHB1dApudW1fc2ltcyA8LSAxMDAwCnNpbV9saXN0XzkwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzkwX2MgPC0gdmVjdG9yKCJsaXN0IiwgbGVuZ3RoID0gbnVtX3NpbXMpCgpmb3IgKGkgaW4gMTpudW1fc2ltcyl7CiAgc2V0LnNlZWQoaSkKICAKICBOX2MgPC0gICAgIHN1bShzYW1wbGUoY2FtcHMuZGF0YSRjYW1wX3RvdGFsLCAxNCkpICAgICMgU2FtcGxlIGRpZmZlcmVudCBwYXRjaCBzaXplcyBmb3IgZWFjaCBzaW0KICAKICB4MF9jIDwtIGMoTl9jIC0gaW5pdGlhbF9pbmZlY3RlZCwgaW5pdGlhbF9pbmZlY3RlZCwgMCwgMCwgTl9jKQoKICBuYW1lcyh4MF9jKSA8LSBjKCJTIiwiRSIsIkkiLCAiUiIsICJOIikKCgogIG91dF8xMDBfOTBfYyA8LSBzc2EoCiAgICB4MCA9IHgwX2MsCiAgICBhID0gYSwKICAgIG51ID0gbnUsCiAgICBwYXJtcyA9IHBhcm1zXzkwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfOTBfYyA8LSBvdXRfMTAwXzkwX2MkZGF0YSAlPiUKICAgIGFzX3RpYmJsZSgpICU+JQogICAgc2xpY2VfbWF4KHQpICU+JQogICAgZGlzdGluY3QoKSAlPiUKICAgIHBpdm90X2xvbmdlcighdCwgbmFtZXNfdG8gPSAic3RhdGUiLCB2YWx1ZXNfdG8gPSAiY291bnQiKSAlPiUKICAgIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBzdGF0ZSwgdmFsdWVzX2Zyb20gPSBjb3VudCkgJT4lCiAgICBtdXRhdGUocGVyc2lzdCA9IGNhc2Vfd2hlbihJID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSSA9PSAwIH4gRiksCiAgICAgICAgICAgc2ltID0gaSkgJT4lCiAgICBzZWxlY3Qoc2ltLCBJLCBOLCBwZXJzaXN0KQogIAogIHNpbV9saXN0XzkwX2NbW2ldXSA8LSBzaW1fZGF0YV85MF9jCn0KCnNpbV9vdXRwdXRfOTBfYyA8LSBiaW5kX3Jvd3Moc2ltX2xpc3RfOTBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF85MF9jIDwtIHNpbV9vdXRwdXRfOTBfYyAlPiUKICBncm91cF9ieShzaW0pICU+JQogIHN1bW1hcmlzZSh0b3RhbF9JID0gc3VtKEkpLCAKICAgICAgICAgICAgdG90YWxfTiA9IHN1bShOKSkgJT4lCiAgbXV0YXRlKHBlcmNlbnRfcGVyc2lzdCA9IHRvdGFsX0kvKHRvdGFsX04pKjEwMCwKICAgICAgICAgcGVyc2lzdCA9IGNhc2Vfd2hlbih0b3RhbF9JID4gMCB+IFQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxfSSA9PSAwIH4gRikpCnNpbV9vdXRwdXRfOTBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzkwX2MgPC0gc2ltX291dHB1dF85MF9jICU+JQogIHN1bW1hcmlzZShtZWFuX2luZmVjdGVkcyA9IG1lYW4odG90YWxfSSksCiAgICAgICAgICAgIHN1bV9wZXJzaXN0ID0gKHN1bShwZXJzaXN0LCBuYS5ybSA9IFQpL251bV9zaW1zKSoxMDAsICAgICAgICAgICAgICBtZWFuX3BlcmNlbnRfaW5mZWN0ZWQgPSBtZWFuKHBlcmNlbnRfcGVyc2lzdCkpICU+JQogIG11dGF0ZShvbWVnYSA9IDEvOTApCnNpbV9zdW1tYXJ5XzkwX2MKYGBgCgoKIyMjIyAxMTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xMTAgPC0gcGFybXMKcGFybXNfMTEwJG9tZWdhIDwtIDEvMTEwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTEwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzExMF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzExMF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTEwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTEwX2MgPC0gb3V0XzEwMF8xMTBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTEwX2NbW2ldXSA8LSBzaW1fZGF0YV8xMTBfYwp9CgpzaW1fb3V0cHV0XzExMF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xMTBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xMTBfYyA8LSBzaW1fb3V0cHV0XzExMF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xMTBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzExMF9jIDwtIHNpbV9vdXRwdXRfMTEwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMTApCnNpbV9zdW1tYXJ5XzExMF9jCmBgYAoKIyMjIyAxMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xMjAgPC0gcGFybXMKcGFybXNfMTIwJG9tZWdhIDwtIDEvMTIwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTIwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzEyMF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzEyMF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTIwX2MgPC0gb3V0XzEwMF8xMjBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTIwX2NbW2ldXSA8LSBzaW1fZGF0YV8xMjBfYwp9CgpzaW1fb3V0cHV0XzEyMF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xMjBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xMjBfYyA8LSBzaW1fb3V0cHV0XzEyMF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xMjBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEyMF9jIDwtIHNpbV9vdXRwdXRfMTIwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMjApCnNpbV9zdW1tYXJ5XzEyMF9jCmBgYAoKIyMjIyAxMzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xMzAgPC0gcGFybXMKcGFybXNfMTMwJG9tZWdhIDwtIDEvMTMwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTMwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzEzMF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzEzMF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTMwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTMwX2MgPC0gb3V0XzEwMF8xMzBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTMwX2NbW2ldXSA8LSBzaW1fZGF0YV8xMzBfYwp9CgpzaW1fb3V0cHV0XzEzMF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xMzBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xMzBfYyA8LSBzaW1fb3V0cHV0XzEzMF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xMzBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzEzMF9jIDwtIHNpbV9vdXRwdXRfMTMwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xMzApCnNpbV9zdW1tYXJ5XzEzMF9jCmBgYAoKIyMjIyAxNTAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xNTAgPC0gcGFybXMKcGFybXNfMTUwJG9tZWdhIDwtIDEvMTUwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTUwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzE1MF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzE1MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTUwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTUwX2MgPC0gb3V0XzEwMF8xNTBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTUwX2NbW2ldXSA8LSBzaW1fZGF0YV8xNTBfYwp9CgpzaW1fb3V0cHV0XzE1MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xNTBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xNTBfYyA8LSBzaW1fb3V0cHV0XzE1MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xNTBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE1MF9jIDwtIHNpbV9vdXRwdXRfMTUwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xNTApCnNpbV9zdW1tYXJ5XzE1MF9jCmBgYAoKIyMjIyAxODAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18xODAgPC0gcGFybXMKcGFybXNfMTgwJG9tZWdhIDwtIDEvMTgwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMTgwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzE4MF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzE4MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMTgwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMTgwX2MgPC0gb3V0XzEwMF8xODBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMTgwX2NbW2ldXSA8LSBzaW1fZGF0YV8xODBfYwp9CgpzaW1fb3V0cHV0XzE4MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8xODBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8xODBfYyA8LSBzaW1fb3V0cHV0XzE4MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8xODBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzE4MF9jIDwtIHNpbV9vdXRwdXRfMTgwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8xODApCnNpbV9zdW1tYXJ5XzE4MF9jCmBgYAoKIyMjIyAyMjAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18yMjAgPC0gcGFybXMKcGFybXNfMjIwJG9tZWdhIDwtIDEvMjIwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMjIwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzIyMF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzIyMF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMjIwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMjIwX2MgPC0gb3V0XzEwMF8yMjBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMjIwX2NbW2ldXSA8LSBzaW1fZGF0YV8yMjBfYwp9CgpzaW1fb3V0cHV0XzIyMF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8yMjBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8yMjBfYyA8LSBzaW1fb3V0cHV0XzIyMF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8yMjBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzIyMF9jIDwtIHNpbV9vdXRwdXRfMjIwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yMjApCnNpbV9zdW1tYXJ5XzIyMF9jCmBgYAoKIyMjIyAyNzAgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18yNzAgPC0gcGFybXMKcGFybXNfMjcwJG9tZWdhIDwtIDEvMjcwCgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMjcwX2MgPC0gbGlzdCgpCnNpbV9saXN0XzI3MF9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzI3MF9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMjcwLAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMjcwX2MgPC0gb3V0XzEwMF8yNzBfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMjcwX2NbW2ldXSA8LSBzaW1fZGF0YV8yNzBfYwp9CgpzaW1fb3V0cHV0XzI3MF9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8yNzBfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8yNzBfYyA8LSBzaW1fb3V0cHV0XzI3MF9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8yNzBfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzI3MF9jIDwtIHNpbV9vdXRwdXRfMjcwX2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8yNzApCnNpbV9zdW1tYXJ5XzI3MF9jCmBgYAoKIyMjIyAzNjUgRGF5cwpgYGB7cn0KI0NvbGxlY3QgcGFyYW1ldGVycwpwYXJtc18zNjUgPC0gcGFybXMKcGFybXNfMzY1JG9tZWdhIDwtIDEvMzY1CgoKIyMgUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGFuZCBzYXZpbmcgb3V0cHV0Cm51bV9zaW1zIDwtIDEwMDAKc2ltX2xpc3RfMzY1X2MgPC0gbGlzdCgpCnNpbV9saXN0XzM2NV9jIDwtIHZlY3RvcigibGlzdCIsIGxlbmd0aCA9IG51bV9zaW1zKQoKZm9yIChpIGluIDE6bnVtX3NpbXMpewogIHNldC5zZWVkKGkpCiAgCiAgTl9jIDwtICAgICBzdW0oc2FtcGxlKGNhbXBzLmRhdGEkY2FtcF90b3RhbCwgMTQpKSAgICAjIFNhbXBsZSBkaWZmZXJlbnQgcGF0Y2ggc2l6ZXMgZm9yIGVhY2ggc2ltCiAgCiAgeDBfYyA8LSBjKE5fYyAtIGluaXRpYWxfaW5mZWN0ZWQsIGluaXRpYWxfaW5mZWN0ZWQsIDAsIDAsIE5fYykKCiAgbmFtZXMoeDBfYykgPC0gYygiUyIsIkUiLCJJIiwgIlIiLCAiTiIpCgoKICBvdXRfMTAwXzM2NV9jIDwtIHNzYSgKICAgIHgwID0geDBfYywKICAgIGEgPSBhLAogICAgbnUgPSBudSwKICAgIHBhcm1zID0gcGFybXNfMzY1LAogICAgdGYgPSB0ZiwKICAgIG1ldGhvZCA9IHNzYS5kKCksCiAgICBzaW1OYW1lID0gc2ltTmFtZSwKICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgIGNvbnNvbGVJbnRlcnZhbCA9IDEKICApCgogIAojIEV4dHJhY3QgRmluYWwgdGltZSBwb2ludCBmcm9tIG91dHB1dCBkYXRhCiAgc2ltX2RhdGFfMzY1X2MgPC0gb3V0XzEwMF8zNjVfYyRkYXRhICU+JQogICAgYXNfdGliYmxlKCkgJT4lCiAgICBzbGljZV9tYXgodCkgJT4lCiAgICBkaXN0aW5jdCgpICU+JQogICAgcGl2b3RfbG9uZ2VyKCF0LCBuYW1lc190byA9ICJzdGF0ZSIsIHZhbHVlc190byA9ICJjb3VudCIpICU+JQogICAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IHN0YXRlLCB2YWx1ZXNfZnJvbSA9IGNvdW50KSAlPiUKICAgIG11dGF0ZShwZXJzaXN0ID0gY2FzZV93aGVuKEkgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJID09IDAgfiBGKSwKICAgICAgICAgICBzaW0gPSBpKSAlPiUKICAgIHNlbGVjdChzaW0sIEksIE4sIHBlcnNpc3QpCiAgCiAgc2ltX2xpc3RfMzY1X2NbW2ldXSA8LSBzaW1fZGF0YV8zNjVfYwp9CgpzaW1fb3V0cHV0XzM2NV9jIDwtIGJpbmRfcm93cyhzaW1fbGlzdF8zNjVfYykKYGBgCgpgYGB7cn0KIyBTdW1tYXJ5IHRhYmxlIG9mIGVuZHBvaW50IGRhdGEKc2ltX291dHB1dF8zNjVfYyA8LSBzaW1fb3V0cHV0XzM2NV9jICU+JQogIGdyb3VwX2J5KHNpbSkgJT4lCiAgc3VtbWFyaXNlKHRvdGFsX0kgPSBzdW0oSSksIAogICAgICAgICAgICB0b3RhbF9OID0gc3VtKE4pKSAlPiUKICBtdXRhdGUocGVyY2VudF9wZXJzaXN0ID0gdG90YWxfSS8odG90YWxfTikqMTAwLAogICAgICAgICBwZXJzaXN0ID0gY2FzZV93aGVuKHRvdGFsX0kgPiAwIH4gVCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbF9JID09IDAgfiBGKSkKc2ltX291dHB1dF8zNjVfYwoKIyBNYWtlIFN1bW1hcnkgVGFibGUgb2Ygb3V0cHV0CnNpbV9zdW1tYXJ5XzM2NV9jIDwtIHNpbV9vdXRwdXRfMzY1X2MgJT4lCiAgc3VtbWFyaXNlKG1lYW5faW5mZWN0ZWRzID0gbWVhbih0b3RhbF9JKSwKICAgICAgICAgICAgc3VtX3BlcnNpc3QgPSAoc3VtKHBlcnNpc3QsIG5hLnJtID0gVCkvbnVtX3NpbXMpKjEwMCwgICAgICAgICAgICAgIG1lYW5fcGVyY2VudF9pbmZlY3RlZCA9IG1lYW4ocGVyY2VudF9wZXJzaXN0KSkgJT4lCiAgbXV0YXRlKG9tZWdhID0gMS8zNjUpCnNpbV9zdW1tYXJ5XzM2NV9jCmBgYAoKCgojIyMjIFJlc3VsdHMKYGBge3J9CndhbmluZ19yZXN1bHRzX3NpbmdsZV9jIDwtIHNpbV9zdW1tYXJ5X2MgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzFfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzNfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzdfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzEwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8yMF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMzBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzQwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV81MF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfNjBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzcwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV84MF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfOTBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzExMF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTIwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8xMzBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzE1MF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMTgwX2MpICU+JQogIGJpbmRfcm93cyhzaW1fc3VtbWFyeV8yMjBfYykgJT4lCiAgYmluZF9yb3dzKHNpbV9zdW1tYXJ5XzI3MF9jKSAlPiUKICBiaW5kX3Jvd3Moc2ltX3N1bW1hcnlfMzY1X2MpICU+JQogIG11dGF0ZShpbW11bml0eV9kdXJhdGlvbiA9IDEvb21lZ2EpICU+JQogIGFycmFuZ2UoaW1tdW5pdHlfZHVyYXRpb24pICU+JQogIG11dGF0ZShtb2RlbD0ic2luZ2xlIiwKICAgICAgICAgcGF0Y2hlcyA9IDE0KQoKd3JpdGVfY3N2KHdhbmluZ19yZXN1bHRzX3NpbmdsZV9jLCBmaWxlID0gIi9Vc2Vycy9tYXR0aGV3aG95bGUvR2l0aHViX1JfcHJvamVjdHMvSHVudGVyX0dhdGhlcmVyX21vZGVscy9SZXN1bHRzL3dhbmluZ19yZXN1bHRzX3NpbmdsZV9jLmNzdiIpCgp3YW5pbmdfcmVzdWx0c19zaW5nbGVfYwoKYGBgCgpgYGB7cn0KZ2dwbG90KHdhbmluZ19yZXN1bHRzX3NpbmdsZV9jLCBhZXMoaW1tdW5pdHlfZHVyYXRpb24sIHN1bV9wZXJzaXN0KSkgKwogIGdlb21fbGluZSgpKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9idygpCmBgYAojIyBDb21iaW5lZCBNZXRhIGFuZCBTaW5nbGUgUmVzdWx0cwpgYGB7cn0KY29tYmluZWRfd2FuaW5nXzIgPC0gcmVhZF9jc3YoIlJlc3VsdHMvY29tYmluZWRfd2FuaW5nX3Jlc3VsdHMuY3N2IiklPiUKICBiaW5kX3Jvd3Mod2FuaW5nX3Jlc3VsdHNfc2luZ2xlX2EpICU+JQogIGJpbmRfcm93cyh3YW5pbmdfcmVzdWx0c19zaW5nbGVfYikgJT4lCiAgYmluZF9yb3dzKHdhbmluZ19yZXN1bHRzX3NpbmdsZV9jKQoKY29tYmluZWRfd2FuaW5nXzIKCndyaXRlX2Nzdihjb21iaW5lZF93YW5pbmdfMiwgIlJlc3VsdHMvY29tYmluZWRfd2FuaW5nX3Jlc3VsdHNfMi5jc3YiKQpgYGAKCmBgYHtyfQoKY29tYmluZWRfcGxvdF8yIDwtIGdncGxvdChjb21iaW5lZF93YW5pbmdfMiwgYWVzKGltbXVuaXR5X2R1cmF0aW9uLCBzdW1fcGVyc2lzdCwgY29sb3VyID0gYXMuZmFjdG9yKHBhdGNoZXMpLCBsaW5ldHlwZSA9IG1vZGVsKSkrCiAgZ2VvbV9saW5lKGFscGhhPTAuOSwgc2l6ZT0xKSsKICAjZ2VvbV9wb2ludChhbHBoYT0wLjUsIHNpemU9MS41KSsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLCAzNjAsIDUwKSkgKwogIGxhYnMoeCA9ICJEdXJhdGlvbiBvZiBpbW11bml0eSAoZGF5cykiLAogICAgICAgeSA9ICJQcm9iYWJpbGl0eSBvZiBwZXJzaXN0ZW5jZSBhZnRlciAzIHllYXJzICglKSIsIAogICAgICAgY29sb3VyID0gIk5vLiBDYW1wcyIsCiAgICAgICBsaW5ldHlwZSA9ICJNb2RlbCBUeXBlIikrCiAgc2NhbGVfY29sb3JfZGlzY3JldGUodHlwZSA9IHBhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICN3ZXNfcGFsZXR0ZXMkQXN0ZXJvaWRDaXR5MywKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCIxIiwgIjMiLCAiNyIsICIxNCIpKSsKICBzY2FsZV9saW5ldHlwZV9kaXNjcmV0ZShsYWJlbHMgPSBjKCJNZXRhcG9wdWxhdGlvbiIsICJTaW5nbGUgUG9wdWxhdGlvbiIpKSArCiAgdGhlbWVfYncoKQoKY29tYmluZWRfcGxvdF8yCmBgYApgYGB7cn0KZ2dzYXZlKGZpbGVuYW1lID0gImNvbWJpbmVkX3Bsb3RfcGF0Y2hlc18yLnBkZiIsIHBsb3QgPSBjb21iaW5lZF9wbG90XzIsIGRldmljZSA9ICJwZGYiLCB3aWR0aCA9IDcsIGhlaWdodCA9IDUsIHBhdGggPSAiL1VzZXJzL21hdHRoZXdob3lsZS9HaXRodWJfUl9wcm9qZWN0cy9IdW50ZXJfR2F0aGVyZXJfbW9kZWxzL1Bsb3RzIikKYGBgCgpgYGB7cn0KcGF0aG9nZW5YX3Jlc3VsdHMgPC0gY29tYmluZWRfd2FuaW5nXzIgJT4lCiAgZmlsdGVyKG9tZWdhID09IDAuMDEpCgpwYXRob2dlblhfcmVzdWx0cwpgYGAKCgpgYGB7cn0KcGF0aG9nZW5YX2JhciA8LSBnZ3Bsb3QocGF0aG9nZW5YX3Jlc3VsdHMsIGFlcyhhcy5mYWN0b3IocGF0Y2hlcyksIHN1bV9wZXJzaXN0LCBncm91cE5hbWUgPSBtb2RlbCwgZmlsbCA9IG1vZGVsKSkgKwogIGdlb21fY29sKHBvc2l0aW9uPXBvc2l0aW9uX2RvZGdlKCksIGNvbG91ciA9ICJibGFjayIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDAsIDEwMCwgMTApKSArCiAgbGFicyh4ID0gIk5vLiBDYW1wcyIsCiAgICAgICB5ID0gIlByb2JhYmlsaXR5IG9mIHBlcnNpc3RlbmNlIGFmdGVyIDMgeWVhcnMgKCUpIiwKICAgICAgIGZpbGwgPSAiTW9kZWwgVHlwZSIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKAogICAgdHlwZSA9IHdlc19wYWxldHRlcyRBc3Rlcm9pZENpdHkzLAogICAgbGFiZWxzID0gYygiTWV0YXBvcHVsYXRpb24iLCAiU2luZ2xlIFBvcHVsYXRpb24iKSkgKwogIHRoZW1lX2J3KCkKCnBhdGhvZ2VuWF9iYXIKYGBgCmBgYHtyfQpnZ3NhdmUoZmlsZW5hbWUgPSAicGF0aG9nZW5YX2Jhci5wZGYiLCBwbG90ID0gcGF0aG9nZW5YX2JhciwgZGV2aWNlID0gInBkZiIsIHdpZHRoID0gNywgaGVpZ2h0ID0gNCwgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUGxvdHMiKQoKYGBgCgojIyBDb21iaW5lZCBwbG90cwpgYGB7cn0KbGlicmFyeShnZ3B1YnIpCmxpYnJhcnkoZ3JpZCkKdGhlbWVfc2V0KHRoZW1lX3B1YnIoKSkKCmRvdWJsZV9jb21iaW5lZF9wbG90IDwtIGdnYXJyYW5nZShjb21iaW5lZF9wbG90ICsgcnJlbW92ZSgieGxhYiIpICsgcnJlbW92ZSgieWxhYiIpLCBjb21iaW5lZF9wbG90XzIgKyBycmVtb3ZlKCJ4bGFiIikgKyBycmVtb3ZlKCJ5bGFiIiksCiAgICAgICAgICBsYWJlbHMgPSBjKCJBIiwgIkIiKSwKICAgICAgICAgIGZvbnQubGFiZWwgPSBsaXN0KHNpemUgPSAxMiwgZmFjZSA9ICJwbGFpbiIpLAogICAgICAgICAgdmp1c3QgPSAxLAogICAgICAgICAgbmNvbCA9IDIsIG5yb3cgPSAxLAogICAgICAgICAgbGVnZW5kLmdyb2IgPSBnZXRfbGVnZW5kKGNvbWJpbmVkX3Bsb3RfMiksCiAgICAgICAgICBsZWdlbmQgPSAicmlnaHQiCiAgICAgICAgICApCgpkb3VibGVfY29tYmluZWRfcGxvdCA8LSBhbm5vdGF0ZV9maWd1cmUoZG91YmxlX2NvbWJpbmVkX3Bsb3QsIGxlZnQgPSB0ZXh0R3JvYigiUHJvYmFiaWxpdHkgb2YgcGVyc2lzdGVuY2UgYWZ0ZXIgMyB5ZWFycyAoJSkiLCByb3QgPSA5MCwgdmp1c3QgPSAxLCBncCA9IGdwYXIoY2V4ID0gMSkpLAogICAgICAgICAgICAgICAgICAgIGJvdHRvbSA9IHRleHRHcm9iKCJEdXJhdGlvbiBvZiBpbW11bml0eSAoZGF5cykiLCBoanVzdCA9IDAuOCwgZ3AgPSBncGFyKGNleCA9IDEpKSkKCmRvdWJsZV9jb21iaW5lZF9wbG90CmBgYApgYGB7cn0KZ2dzYXZlKGZpbGVuYW1lID0gImRvdWJsZV9pbW11bml0eV9wbG90LnBkZiIsIHBsb3QgPSBkb3VibGVfY29tYmluZWRfcGxvdCwgZGV2aWNlID0gInBkZiIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gNCwgcGF0aCA9ICIvVXNlcnMvbWF0dGhld2hveWxlL0dpdGh1Yl9SX3Byb2plY3RzL0h1bnRlcl9HYXRoZXJlcl9tb2RlbHMvUGxvdHMiKQpgYGAKCgoKIyMgR0xNIEFuYWx5c2lzCiMjIyBNb2RlbCBTZWxlY3Rpb24KCmBgYHtyfQptb2RlbDEgPC0gZ2xtKGFzLmludGVnZXIoc3VtX3BlcnNpc3QpIH4gCiAgICAgICAgICAgICAgICBpbW11bml0eV9kdXJhdGlvbiArIAogICAgICAgICAgICAgICAgYXMuZmFjdG9yKG1vZGVsKSArIAogICAgICAgICAgICAgICAgYXMuZmFjdG9yKHBhdGNoZXMpICsgCiAgICAgICAgICAgICAgICBhcy5mYWN0b3IobW9kZWwpKmltbXVuaXR5X2R1cmF0aW9uICsgCiAgICAgICAgICAgICAgICBhcy5mYWN0b3IocGF0Y2hlcykqaW1tdW5pdHlfZHVyYXRpb24gKyAKICAgICAgICAgICAgICAgIGFzLmZhY3Rvcihtb2RlbCkqYXMuZmFjdG9yKHBhdGNoZXMpLCAKICAgICAgICAgICAgICBmYW1pbHkgPSAicG9pc3NvbiIsIGRhdGEgPSBjb21iaW5lZF93YW5pbmdfMikKCnN1bW1hcnkobW9kZWwxKQpgYGAKCmBgYHtyfQptb2RlbDIgPC0gZ2xtKGFzLmludGVnZXIoc3VtX3BlcnNpc3QpIH4gCiAgICAgICAgICAgICAgICBpbW11bml0eV9kdXJhdGlvbiArIAogICAgICAgICAgICAgICAgYXMuZmFjdG9yKG1vZGVsKSArIAogICAgICAgICAgICAgICAgYXMuZmFjdG9yKHBhdGNoZXMpICsKICAgICAgICAgICAgICAgIGFzLmZhY3Rvcihtb2RlbCkqaW1tdW5pdHlfZHVyYXRpb24gKyAKICAgICAgICAgICAgICAgIGFzLmZhY3RvcihwYXRjaGVzKSppbW11bml0eV9kdXJhdGlvbiwgCiAgICAgICAgICAgICAgZmFtaWx5ID0gInBvaXNzb24iLCBkYXRhID0gY29tYmluZWRfd2FuaW5nXzIpCgpzdW1tYXJ5KG1vZGVsMikKYGBgCgpgYGB7cn0KbGlicmFyeShsbXRlc3QpCgpscnRlc3QobW9kZWwxLCBtb2RlbDIpCmBgYApgYGB7cn0KbW9kZWwzIDwtIGdsbShhcy5pbnRlZ2VyKHN1bV9wZXJzaXN0KSB+IAogICAgICAgICAgICAgICAgaW1tdW5pdHlfZHVyYXRpb24gKyAKICAgICAgICAgICAgICAgIGFzLmZhY3Rvcihtb2RlbCkgKyAKICAgICAgICAgICAgICAgIGFzLmZhY3RvcihwYXRjaGVzKSArIAogICAgICAgICAgICAgICAgYXMuZmFjdG9yKHBhdGNoZXMpKmltbXVuaXR5X2R1cmF0aW9uLCAKICAgICAgICAgICAgICBmYW1pbHkgPSAicG9pc3NvbiIsIGRhdGEgPSBjb21iaW5lZF93YW5pbmdfMikKCnN1bW1hcnkobW9kZWwzKQpgYGAKCmBgYHtyfQpscnRlc3QobW9kZWwyLCBtb2RlbDMpCmBgYApgYGB7cn0KbW9kZWw0IDwtIGdsbShhcy5pbnRlZ2VyKHN1bV9wZXJzaXN0KSB+IGltbXVuaXR5X2R1cmF0aW9uICsKICAgICAgICAgICAgICAgIGFzLmZhY3RvcihwYXRjaGVzKSArCiAgICAgICAgICAgICAgICBhcy5mYWN0b3IocGF0Y2hlcykqaW1tdW5pdHlfZHVyYXRpb24sIAogICAgICAgICAgICAgIGZhbWlseSA9ICJwb2lzc29uIiwgZGF0YSA9IGNvbWJpbmVkX3dhbmluZ18yKQoKc3VtbWFyeShtb2RlbDQpCmBgYApgYGB7cn0KbHJ0ZXN0KG1vZGVsMywgbW9kZWw0KQpgYGAKIyMjIEZpbmFsIEdMTQpgYGB7cn0Kc3VtbWFyeShtb2RlbDMpCmBgYAoKIyMjIFNpZ25pZmljYW5jZSBvZiBDb2VmZmljaWVudHMKYGBge3J9Cm1vZGVsNSA8LSBnbG0oYXMuaW50ZWdlcihzdW1fcGVyc2lzdCkgfiAKICAgICAgICAgICAgICAgIGltbXVuaXR5X2R1cmF0aW9uICsgCiAgICAgICAgICAgICAgICBhcy5mYWN0b3IobW9kZWwpICsgCiAgICAgICAgICAgICAgICBhcy5mYWN0b3IocGF0Y2hlcykgKyAKICAgICAgICAgICAgICAgIGFzLmZhY3RvcihwYXRjaGVzKSppbW11bml0eV9kdXJhdGlvbiwgCiAgICAgICAgICAgICAgZmFtaWx5ID0gInBvaXNzb24iLCBkYXRhID0gY29tYmluZWRfd2FuaW5nXzIpCmBgYAoKCiMjIFJlZmVyZW5jZXMKCgo=